Gary Munnelly 2 veckor sedan
incheckning
3a14c9b7b6
100 ändrade filer med 14459 tillägg och 0 borttagningar
  1. 2 0
      .gitignore
  2. 6 0
      Assets/Actors/afternoon_sky.xml
  3. 27 0
      Assets/Actors/ai_teapot.xml
  4. 23 0
      Assets/Actors/grid.xml
  5. 16 0
      Assets/Actors/light.xml
  6. 7 0
      Assets/Actors/music.xml
  7. 23 0
      Assets/Actors/player_teapot.xml
  8. 26 0
      Assets/Actors/remote_teapot.xml
  9. 26 0
      Assets/Actors/sphere.xml
  10. BIN
      Assets/Art/Grid.bmp
  11. BIN
      Assets/Art/Gridalpha.bmp
  12. BIN
      Assets/Art/Sky2_E.JPG
  13. BIN
      Assets/Art/Sky2_N.JPG
  14. BIN
      Assets/Art/Sky2_S.JPG
  15. BIN
      Assets/Art/Sky2_U.JPG
  16. BIN
      Assets/Art/Sky2_W.JPG
  17. BIN
      Assets/Art/Teapot.sdkmesh
  18. BIN
      Assets/Art/grid.dds
  19. BIN
      Assets/Art/grid.jpg
  20. BIN
      Assets/Art/grid_nomips.dds
  21. BIN
      Assets/Art/grid_nomips.jpg
  22. BIN
      Assets/Art/sphere.blend
  23. BIN
      Assets/Art/sphere.sdkmesh
  24. 5029 0
      Assets/Art/sphere.x
  25. BIN
      Assets/Art/teapot.glb
  26. BIN
      Assets/Art/texture.dds
  27. BIN
      Assets/Art/texture.jpg
  28. 3 0
      Assets/Audio/Sources.txt
  29. BIN
      Assets/Audio/SpaceGod7-Level2.ogg
  30. BIN
      Assets/Audio/blip.ogg
  31. BIN
      Assets/Audio/blip.wav
  32. BIN
      Assets/Audio/blip16.wav
  33. BIN
      Assets/Audio/computerbeep3.ogg
  34. BIN
      Assets/Audio/computerbeep3.wav
  35. 96 0
      Assets/Config/physics.xml
  36. 54 0
      Assets/Editor/components.xml
  37. 191 0
      Assets/Effects/GameCode4.fx
  38. 80 0
      Assets/Effects/GameCode4_PS.hlsl
  39. 112 0
      Assets/Effects/GameCode4_VS.hlsl
  40. 27 0
      Assets/Effects/GameCode4_frag.glsl
  41. 61 0
      Assets/Effects/GameCode4_vert.glsl
  42. 172 0
      Assets/Effects/LineDraw.hlsl
  43. 58 0
      Assets/Scripts/ActorManager.lua
  44. 52 0
      Assets/Scripts/LevelInit.lua
  45. 1 0
      Assets/Scripts/LevelPostInit.lua
  46. 171 0
      Assets/Scripts/PreInit.lua
  47. 53 0
      Assets/Scripts/test.lua
  48. 25 0
      Assets/Strings/English.xml
  49. 27 0
      Assets/World/World.xml
  50. 48 0
      Assets/World/WorldInstances.xml
  51. 8 0
      CMakeLists.txt
  52. BIN
      Game/Assets.zip
  53. 7 0
      Game/Logging.xml
  54. 7 0
      Game/PlayerOptions.xml
  55. 8 0
      README.md
  56. 154 0
      Source/CMakeLists.txt
  57. 92 0
      Source/GCC4/Actors/Actor.cpp
  58. 114 0
      Source/GCC4/Actors/Actor.h
  59. 76 0
      Source/GCC4/Actors/ActorComponent.h
  60. 191 0
      Source/GCC4/Actors/ActorFactory.cpp
  61. 71 0
      Source/GCC4/Actors/ActorFactory.h
  62. 121 0
      Source/GCC4/Actors/AudioComponent.cpp
  63. 67 0
      Source/GCC4/Actors/AudioComponent.h
  64. 200 0
      Source/GCC4/Actors/BaseScriptComponent.cpp
  65. 74 0
      Source/GCC4/Actors/BaseScriptComponent.h
  66. 323 0
      Source/GCC4/Actors/RenderComponent.cpp
  67. 157 0
      Source/GCC4/Actors/RenderComponent.h
  68. 50 0
      Source/GCC4/Actors/RenderComponentInterface.h
  69. 53 0
      Source/GCC4/Actors/ScriptComponentInterface.h
  70. 122 0
      Source/GCC4/Actors/TransformComponent.cpp
  71. 63 0
      Source/GCC4/Actors/TransformComponent.h
  72. 387 0
      Source/GCC4/Debugging/Logger.cpp
  73. 185 0
      Source/GCC4/Debugging/Logger.h
  74. 72 0
      Source/GCC4/EventManager/EventManager.cpp
  75. 146 0
      Source/GCC4/EventManager/EventManager.h
  76. 249 0
      Source/GCC4/EventManager/EventManagerImpl.cpp
  77. 65 0
      Source/GCC4/EventManager/EventManagerImpl.h
  78. 63 0
      Source/GCC4/EventManager/Events.cpp
  79. 507 0
      Source/GCC4/EventManager/Events.h
  80. 449 0
      Source/GCC4/GameCode4/BaseGameLogic.cpp
  81. 152 0
      Source/GCC4/GameCode4/BaseGameLogic.h
  82. 588 0
      Source/GCC4/GameCode4/GameCode.cpp
  83. 159 0
      Source/GCC4/GameCode4/GameCode.h
  84. 77 0
      Source/GCC4/GameCode4/GameCode4.cpp
  85. 327 0
      Source/GCC4/GameCode4/interfaces.h
  86. 91 0
      Source/GCC4/Graphics3D/Geometry.cpp
  87. 245 0
      Source/GCC4/Graphics3D/Geometry.h
  88. 94 0
      Source/GCC4/Graphics3D/Lights.cpp
  89. 131 0
      Source/GCC4/Graphics3D/Lights.h
  90. 192 0
      Source/GCC4/Graphics3D/Material.cpp
  91. 103 0
      Source/GCC4/Graphics3D/Material.h
  92. 182 0
      Source/GCC4/Graphics3D/Mesh.cpp
  93. 116 0
      Source/GCC4/Graphics3D/Mesh.h
  94. 255 0
      Source/GCC4/Graphics3D/MovementController.cpp
  95. 99 0
      Source/GCC4/Graphics3D/MovementController.h
  96. 76 0
      Source/GCC4/Graphics3D/OpenGLRenderer.cpp
  97. 59 0
      Source/GCC4/Graphics3D/OpenGLRenderer.h
  98. 230 0
      Source/GCC4/Graphics3D/Scene.cpp
  99. 140 0
      Source/GCC4/Graphics3D/Scene.h
  100. 646 0
      Source/GCC4/Graphics3D/SceneNodes.cpp

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+Build
+Vendor

+ 6 - 0
Assets/Actors/afternoon_sky.xml

@@ -0,0 +1,6 @@
+<Actor type="Sky" resource="actors/afternoon_sky.xml">
+    <SkyRenderComponent>
+        <Color r="1.0" g="1.0" b="1.0" a="1.0"/>
+        <Texture>art/sky2_n.jpg</Texture>
+    </SkyRenderComponent>
+</Actor>

+ 27 - 0
Assets/Actors/ai_teapot.xml

@@ -0,0 +1,27 @@
+<Actor type="Teapot" resource="actors/ai_teapot.xml">
+
+	<TransformComponent>
+		<Position x="10" y="1.1" z="10"/>
+		<YawPitchRoll x="0" y="0" z="0"/>
+	</TransformComponent>
+
+
+    <PhysicsComponent>
+        <Shape>Box</Shape>
+        <Density>glass</Density>
+        <PhysicsMaterial>Normal</PhysicsMaterial>
+    </PhysicsComponent>
+
+	
+    <TeapotRenderComponent>
+        <Color r="1.0" g="0" b="0" a="1.0"/>
+    </TeapotRenderComponent>
+
+
+    <BaseScriptComponent>
+        <ScriptObject constructor="AddEnemy" destructor="RemoveEnemy" />
+        <ScriptData actorType="Teapot" />
+    </BaseScriptComponent>
+
+	
+</Actor>

+ 23 - 0
Assets/Actors/grid.xml

@@ -0,0 +1,23 @@
+<Actor type="Grid" resource="actors/grid.xml">
+
+	<TransformComponent>
+		<Position x="0" y="0" z="0"/>
+		<YawPitchRoll x="0" y="0" z="0"/>
+	</TransformComponent>
+	
+    <!-- <PhysicsComponent>
+        <Shape>Box</Shape>
+        <Density>Infinite</Density>
+        <PhysicsMaterial>Normal</PhysicsMaterial>
+        <RigidBodyTransform>
+			<Scale x="50" y="0.01" z="50" />  
+		</RigidBodyTransform>
+    </PhysicsComponent> -->
+	
+    <GridRenderComponent>
+        <Color r="0.4" g="0.4" b="0.4" a="1.0"/>
+        <Texture>art/grid.jpg</Texture>
+		<Division>100</Division>
+    </GridRenderComponent>
+
+</Actor>

+ 16 - 0
Assets/Actors/light.xml

@@ -0,0 +1,16 @@
+<Actor type="Light" resource="actors/light.xml">
+
+  <TransformComponent>
+    <Position x="5.0" y="5.0" z="3.0"/>
+	  <YawPitchRoll x="45" y="-45" z="0"/>
+  </TransformComponent>
+
+  <LightRenderComponent>
+    <Color r="0.5" g="1.0" b="0.5" a="1.0"/>
+    <Light>
+      <Attenuation const="0.1" linear="0.0" exp="0.0" />
+      <Shape range="100.0" falloff="1.0" theta="0.0" phi="0.0"/>
+    </Light>
+  </LightRenderComponent>
+
+</Actor>

+ 7 - 0
Assets/Actors/music.xml

@@ -0,0 +1,7 @@
+<Actor type="Music" resource="actors/music.xml">
+	<AudioComponent>
+		<Sound>audio/spacegod7-level2.ogg</Sound>
+		<Loop>1</Loop>
+		<FadeIn>5.0</FadeIn>
+	</AudioComponent>	
+</Actor>

+ 23 - 0
Assets/Actors/player_teapot.xml

@@ -0,0 +1,23 @@
+<Actor type="Teapot" resource="actors/player_teapot.xml">
+
+	<TransformComponent>
+		<Position x="0" y="5" z="0"/>
+		<YawPitchRoll x="0" y="0" z="0"/>
+	</TransformComponent>
+		
+    <!-- <PhysicsComponent>
+        <Shape>Box</Shape>
+        <Density>glass</Density>
+        <PhysicsMaterial>Normal</PhysicsMaterial>
+    </PhysicsComponent> -->
+	
+    <TeapotRenderComponent>
+        <Color r="0" g="0" b="1.0" a="1.0"/>
+    </TeapotRenderComponent>
+
+    <BaseScriptComponent>
+        <ScriptObject constructor="AddPlayer" destructor="RemovePlayer" />
+        <ScriptData actorType="Teapot" />
+    </BaseScriptComponent>
+
+</Actor>

+ 26 - 0
Assets/Actors/remote_teapot.xml

@@ -0,0 +1,26 @@
+<Actor type="Teapot" resource="actors/remote_teapot.xml">
+
+	<TransformComponent>
+		<Position x="0" y="5" z="0"/>
+		<YawPitchRoll x="0" y="0" z="0"/>
+	</TransformComponent>
+		
+    <PhysicsComponent>
+        <Shape>Box</Shape>
+        <Density>glass</Density>
+        <PhysicsMaterial>Normal</PhysicsMaterial>
+
+    </PhysicsComponent>
+
+    <TeapotRenderComponent>
+        <Color r="0" g="1.0" b="0" a="1.0"/>
+    </TeapotRenderComponent>
+
+ <!--  [rez] TODO: Figure out how network players work.  Maybe they don't need a type?
+    <BaseScriptComponent>
+        <ScriptObject constructor="AddEnemy" destructor="RemoveEnemy" />
+        <ScriptData actorType="Teapot" />
+    </BaseScriptComponent>
+-->
+
+</Actor>

+ 26 - 0
Assets/Actors/sphere.xml

@@ -0,0 +1,26 @@
+<Actor type="Sphere" resource="actors/sphere.xml">
+
+	<TransformComponent>
+		<Position x="0" y="5" z="0"/>
+	</TransformComponent>
+	
+    <PhysicsComponent>
+        <Shape>Sphere</Shape>
+        <Density>pine</Density>
+        <PhysicsMaterial>Bouncy</PhysicsMaterial>
+		<RigidBodyTransform>
+			<Scale x="0.25" y="0.25" z="0.25" />  
+		</RigidBodyTransform>
+    </PhysicsComponent>
+
+    <SphereRenderComponent>
+        <Color r="0" g="1.0" b="1.0" a="1.0"/>
+        <Sphere radius="0.25" segments="25"/>
+	</SphereRenderComponent>
+
+    <BaseScriptComponent>
+        <ScriptObject constructor="AddSphere" destructor="RemoveSphere" />
+        <ScriptData actorType="Sphere" />
+    </BaseScriptComponent>
+
+</Actor>

BIN
Assets/Art/Grid.bmp


BIN
Assets/Art/Gridalpha.bmp


BIN
Assets/Art/Sky2_E.JPG


BIN
Assets/Art/Sky2_N.JPG


BIN
Assets/Art/Sky2_S.JPG


BIN
Assets/Art/Sky2_U.JPG


BIN
Assets/Art/Sky2_W.JPG


BIN
Assets/Art/Teapot.sdkmesh


BIN
Assets/Art/grid.dds


BIN
Assets/Art/grid.jpg


BIN
Assets/Art/grid_nomips.dds


BIN
Assets/Art/grid_nomips.jpg


BIN
Assets/Art/sphere.blend


BIN
Assets/Art/sphere.sdkmesh


+ 5029 - 0
Assets/Art/sphere.x

@@ -0,0 +1,5029 @@
+xof 0303txt 0032
+
+Frame Root {
+  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, 0.000000, 0.000000, 1.000000;;
+  }
+  Frame Sphere {
+    FrameTransformMatrix {
+       0.250000, 0.000000, 0.000000, 0.000000,
+       0.000000, 0.250000, 0.000000, 0.000000,
+       0.000000, 0.000000, 0.250000, 0.000000,
+       0.000000, 0.000000, 0.000000, 1.000000;;
+    }
+    Mesh { //Sphere_001 Mesh
+      1984;
+       0.195090; 0.000000;-0.980785;,
+       0.191341; 0.038060;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.195090; 0.000000;-0.980785;,
+       0.382683; 0.000000;-0.923880;,
+       0.375330; 0.074658;-0.923880;,
+       0.191341; 0.038060;-0.980785;,
+       0.544895; 0.108386;-0.831470;,
+       0.375330; 0.074658;-0.923880;,
+       0.382683; 0.000000;-0.923880;,
+       0.555570; 0.000000;-0.831470;,
+       0.693520; 0.137950;-0.707107;,
+       0.544895; 0.108386;-0.831470;,
+       0.555570; 0.000000;-0.831470;,
+       0.707107; 0.000000;-0.707107;,
+       0.815493; 0.162212;-0.555570;,
+       0.693520; 0.137950;-0.707107;,
+       0.707107; 0.000000;-0.707107;,
+       0.831469; 0.000000;-0.555570;,
+       0.906127; 0.180240;-0.382683;,
+       0.815493; 0.162212;-0.555570;,
+       0.831469; 0.000000;-0.555570;,
+       0.923879; 0.000000;-0.382683;,
+       0.961940; 0.191342;-0.195090;,
+       0.906127; 0.180240;-0.382683;,
+       0.923879; 0.000000;-0.382683;,
+       0.980785; 0.000000;-0.195090;,
+       0.980785; 0.195090; 0.000000;,
+       0.961940; 0.191342;-0.195090;,
+       0.980785; 0.000000;-0.195090;,
+       0.999999; 0.000000; 0.000000;,
+       0.961940; 0.191342; 0.195090;,
+       0.980785; 0.195090; 0.000000;,
+       0.999999; 0.000000; 0.000000;,
+       0.980785; 0.000000; 0.195090;,
+       0.906127; 0.180240; 0.382683;,
+       0.961940; 0.191342; 0.195090;,
+       0.980785; 0.000000; 0.195090;,
+       0.923879; 0.000000; 0.382683;,
+       0.815493; 0.162212; 0.555570;,
+       0.906127; 0.180240; 0.382683;,
+       0.923879; 0.000000; 0.382683;,
+       0.831469; 0.000000; 0.555570;,
+       0.693520; 0.137950; 0.707107;,
+       0.815493; 0.162212; 0.555570;,
+       0.831469; 0.000000; 0.555570;,
+       0.707107; 0.000000; 0.707107;,
+       0.544895; 0.108386; 0.831470;,
+       0.693520; 0.137950; 0.707107;,
+       0.707107; 0.000000; 0.707107;,
+       0.555570; 0.000000; 0.831470;,
+       0.375330; 0.074658; 0.923880;,
+       0.544895; 0.108386; 0.831470;,
+       0.555570; 0.000000; 0.831470;,
+       0.382683; 0.000000; 0.923880;,
+       0.191342; 0.038060; 0.980785;,
+       0.375330; 0.074658; 0.923880;,
+       0.382683; 0.000000; 0.923880;,
+       0.195090; 0.000000; 0.980785;,
+       0.191342; 0.038060; 0.980785;,
+       0.195090; 0.000000; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.180240; 0.074658; 0.980785;,
+       0.191342; 0.038060; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.180240; 0.074658; 0.980785;,
+       0.353553; 0.146447; 0.923880;,
+       0.375330; 0.074658; 0.923880;,
+       0.191342; 0.038060; 0.980785;,
+       0.353553; 0.146447; 0.923880;,
+       0.513280; 0.212608; 0.831470;,
+       0.544895; 0.108386; 0.831470;,
+       0.375330; 0.074658; 0.923880;,
+       0.513280; 0.212608; 0.831470;,
+       0.653281; 0.270598; 0.707107;,
+       0.693520; 0.137950; 0.707107;,
+       0.544895; 0.108386; 0.831470;,
+       0.653281; 0.270598; 0.707107;,
+       0.768178; 0.318190; 0.555570;,
+       0.815493; 0.162212; 0.555570;,
+       0.693520; 0.137950; 0.707107;,
+       0.768178; 0.318190; 0.555570;,
+       0.853553; 0.353553; 0.382683;,
+       0.906127; 0.180240; 0.382683;,
+       0.815493; 0.162212; 0.555570;,
+       0.853553; 0.353553; 0.382683;,
+       0.906127; 0.375330; 0.195090;,
+       0.961940; 0.191342; 0.195090;,
+       0.906127; 0.180240; 0.382683;,
+       0.906127; 0.375330; 0.195090;,
+       0.923879; 0.382683; 0.000000;,
+       0.980785; 0.195090; 0.000000;,
+       0.961940; 0.191342; 0.195090;,
+       0.923879; 0.382683; 0.000000;,
+       0.906127; 0.375330;-0.195090;,
+       0.961940; 0.191342;-0.195090;,
+       0.980785; 0.195090; 0.000000;,
+       0.906127; 0.375330;-0.195090;,
+       0.853553; 0.353553;-0.382683;,
+       0.906127; 0.180240;-0.382683;,
+       0.961940; 0.191342;-0.195090;,
+       0.853553; 0.353553;-0.382683;,
+       0.768178; 0.318190;-0.555570;,
+       0.815493; 0.162212;-0.555570;,
+       0.906127; 0.180240;-0.382683;,
+       0.768178; 0.318190;-0.555570;,
+       0.653281; 0.270598;-0.707107;,
+       0.693520; 0.137950;-0.707107;,
+       0.815493; 0.162212;-0.555570;,
+       0.653281; 0.270598;-0.707107;,
+       0.513280; 0.212608;-0.831470;,
+       0.544895; 0.108386;-0.831470;,
+       0.693520; 0.137950;-0.707107;,
+       0.513280; 0.212608;-0.831470;,
+       0.353553; 0.146447;-0.923880;,
+       0.375330; 0.074658;-0.923880;,
+       0.544895; 0.108386;-0.831470;,
+       0.353553; 0.146447;-0.923880;,
+       0.180240; 0.074658;-0.980785;,
+       0.191341; 0.038060;-0.980785;,
+       0.375330; 0.074658;-0.923880;,
+       0.180240; 0.074658;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.191341; 0.038060;-0.980785;,
+       0.162211; 0.108386;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.180240; 0.074658;-0.980785;,
+       0.318190; 0.212607;-0.923880;,
+       0.162211; 0.108386;-0.980785;,
+       0.180240; 0.074658;-0.980785;,
+       0.353553; 0.146447;-0.923880;,
+       0.461940; 0.308658;-0.831470;,
+       0.318190; 0.212607;-0.923880;,
+       0.353553; 0.146447;-0.923880;,
+       0.513280; 0.212608;-0.831470;,
+       0.587938; 0.392847;-0.707107;,
+       0.461940; 0.308658;-0.831470;,
+       0.513280; 0.212608;-0.831470;,
+       0.653281; 0.270598;-0.707107;,
+       0.691342; 0.461940;-0.555570;,
+       0.587938; 0.392847;-0.707107;,
+       0.653281; 0.270598;-0.707107;,
+       0.768178; 0.318190;-0.555570;,
+       0.768178; 0.513280;-0.382683;,
+       0.691342; 0.461940;-0.555570;,
+       0.768178; 0.318190;-0.555570;,
+       0.853553; 0.353553;-0.382683;,
+       0.815493; 0.544895;-0.195090;,
+       0.768178; 0.513280;-0.382683;,
+       0.853553; 0.353553;-0.382683;,
+       0.906127; 0.375330;-0.195090;,
+       0.831469; 0.555570; 0.000000;,
+       0.815493; 0.544895;-0.195090;,
+       0.906127; 0.375330;-0.195090;,
+       0.923879; 0.382683; 0.000000;,
+       0.815493; 0.544895; 0.195090;,
+       0.831469; 0.555570; 0.000000;,
+       0.923879; 0.382683; 0.000000;,
+       0.906127; 0.375330; 0.195090;,
+       0.768178; 0.513280; 0.382683;,
+       0.815493; 0.544895; 0.195090;,
+       0.906127; 0.375330; 0.195090;,
+       0.853553; 0.353553; 0.382683;,
+       0.691342; 0.461940; 0.555570;,
+       0.768178; 0.513280; 0.382683;,
+       0.853553; 0.353553; 0.382683;,
+       0.768178; 0.318190; 0.555570;,
+       0.587938; 0.392847; 0.707107;,
+       0.691342; 0.461940; 0.555570;,
+       0.768178; 0.318190; 0.555570;,
+       0.653281; 0.270598; 0.707107;,
+       0.461940; 0.308658; 0.831470;,
+       0.587938; 0.392847; 0.707107;,
+       0.653281; 0.270598; 0.707107;,
+       0.513280; 0.212608; 0.831470;,
+       0.318190; 0.212608; 0.923880;,
+       0.461940; 0.308658; 0.831470;,
+       0.513280; 0.212608; 0.831470;,
+       0.353553; 0.146447; 0.923880;,
+       0.162212; 0.108386; 0.980785;,
+       0.318190; 0.212608; 0.923880;,
+       0.353553; 0.146447; 0.923880;,
+       0.180240; 0.074658; 0.980785;,
+       0.162212; 0.108386; 0.980785;,
+       0.180240; 0.074658; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.137950; 0.137950; 0.980785;,
+       0.162212; 0.108386; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.137950; 0.137950; 0.980785;,
+       0.270598; 0.270598; 0.923880;,
+       0.318190; 0.212608; 0.923880;,
+       0.162212; 0.108386; 0.980785;,
+       0.270598; 0.270598; 0.923880;,
+       0.392847; 0.392847; 0.831470;,
+       0.461940; 0.308658; 0.831470;,
+       0.318190; 0.212608; 0.923880;,
+       0.392847; 0.392847; 0.831470;,
+       0.500000; 0.500000; 0.707107;,
+       0.587938; 0.392847; 0.707107;,
+       0.461940; 0.308658; 0.831470;,
+       0.500000; 0.500000; 0.707107;,
+       0.587938; 0.587938; 0.555570;,
+       0.691342; 0.461940; 0.555570;,
+       0.587938; 0.392847; 0.707107;,
+       0.587938; 0.587938; 0.555570;,
+       0.653281; 0.653281; 0.382683;,
+       0.768178; 0.513280; 0.382683;,
+       0.691342; 0.461940; 0.555570;,
+       0.653281; 0.653281; 0.382683;,
+       0.693520; 0.693520; 0.195090;,
+       0.815493; 0.544895; 0.195090;,
+       0.768178; 0.513280; 0.382683;,
+       0.693520; 0.693520; 0.195090;,
+       0.707107; 0.707107; 0.000000;,
+       0.831469; 0.555570; 0.000000;,
+       0.815493; 0.544895; 0.195090;,
+       0.707107; 0.707107; 0.000000;,
+       0.693520; 0.693520;-0.195090;,
+       0.815493; 0.544895;-0.195090;,
+       0.831469; 0.555570; 0.000000;,
+       0.693520; 0.693520;-0.195090;,
+       0.653281; 0.653281;-0.382683;,
+       0.768178; 0.513280;-0.382683;,
+       0.815493; 0.544895;-0.195090;,
+       0.653281; 0.653281;-0.382683;,
+       0.587938; 0.587938;-0.555570;,
+       0.691342; 0.461940;-0.555570;,
+       0.768178; 0.513280;-0.382683;,
+       0.587938; 0.587938;-0.555570;,
+       0.500000; 0.500000;-0.707107;,
+       0.587938; 0.392847;-0.707107;,
+       0.691342; 0.461940;-0.555570;,
+       0.500000; 0.500000;-0.707107;,
+       0.392847; 0.392847;-0.831470;,
+       0.461940; 0.308658;-0.831470;,
+       0.587938; 0.392847;-0.707107;,
+       0.392847; 0.392847;-0.831470;,
+       0.270598; 0.270598;-0.923880;,
+       0.318190; 0.212607;-0.923880;,
+       0.461940; 0.308658;-0.831470;,
+       0.270598; 0.270598;-0.923880;,
+       0.137949; 0.137949;-0.980785;,
+       0.162211; 0.108386;-0.980785;,
+       0.318190; 0.212607;-0.923880;,
+       0.137949; 0.137949;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.162211; 0.108386;-0.980785;,
+       0.108386; 0.162211;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.137949; 0.137949;-0.980785;,
+       0.212607; 0.318190;-0.923880;,
+       0.108386; 0.162211;-0.980785;,
+       0.137949; 0.137949;-0.980785;,
+       0.270598; 0.270598;-0.923880;,
+       0.308658; 0.461940;-0.831470;,
+       0.212607; 0.318190;-0.923880;,
+       0.270598; 0.270598;-0.923880;,
+       0.392847; 0.392847;-0.831470;,
+       0.392847; 0.587938;-0.707107;,
+       0.308658; 0.461940;-0.831470;,
+       0.392847; 0.392847;-0.831470;,
+       0.500000; 0.500000;-0.707107;,
+       0.461940; 0.691342;-0.555570;,
+       0.392847; 0.587938;-0.707107;,
+       0.500000; 0.500000;-0.707107;,
+       0.587938; 0.587938;-0.555570;,
+       0.513280; 0.768178;-0.382683;,
+       0.461940; 0.691342;-0.555570;,
+       0.587938; 0.587938;-0.555570;,
+       0.653281; 0.653281;-0.382683;,
+       0.544895; 0.815493;-0.195090;,
+       0.513280; 0.768178;-0.382683;,
+       0.653281; 0.653281;-0.382683;,
+       0.693520; 0.693520;-0.195090;,
+       0.555570; 0.831470; 0.000000;,
+       0.544895; 0.815493;-0.195090;,
+       0.693520; 0.693520;-0.195090;,
+       0.707107; 0.707107; 0.000000;,
+       0.544895; 0.815493; 0.195090;,
+       0.555570; 0.831470; 0.000000;,
+       0.707107; 0.707107; 0.000000;,
+       0.693520; 0.693520; 0.195090;,
+       0.513280; 0.768178; 0.382683;,
+       0.544895; 0.815493; 0.195090;,
+       0.693520; 0.693520; 0.195090;,
+       0.653281; 0.653281; 0.382683;,
+       0.461940; 0.691342; 0.555570;,
+       0.513280; 0.768178; 0.382683;,
+       0.653281; 0.653281; 0.382683;,
+       0.587938; 0.587938; 0.555570;,
+       0.392847; 0.587938; 0.707107;,
+       0.461940; 0.691342; 0.555570;,
+       0.587938; 0.587938; 0.555570;,
+       0.500000; 0.500000; 0.707107;,
+       0.308658; 0.461940; 0.831470;,
+       0.392847; 0.587938; 0.707107;,
+       0.500000; 0.500000; 0.707107;,
+       0.392847; 0.392847; 0.831470;,
+       0.212608; 0.318190; 0.923880;,
+       0.308658; 0.461940; 0.831470;,
+       0.392847; 0.392847; 0.831470;,
+       0.270598; 0.270598; 0.923880;,
+       0.108386; 0.162212; 0.980785;,
+       0.212608; 0.318190; 0.923880;,
+       0.270598; 0.270598; 0.923880;,
+       0.137950; 0.137950; 0.980785;,
+       0.108386; 0.162212; 0.980785;,
+       0.137950; 0.137950; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.074658; 0.180240; 0.980785;,
+       0.108386; 0.162212; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.074658; 0.180240; 0.980785;,
+       0.146447; 0.353553; 0.923880;,
+       0.212608; 0.318190; 0.923880;,
+       0.108386; 0.162212; 0.980785;,
+       0.146447; 0.353553; 0.923880;,
+       0.212607; 0.513280; 0.831470;,
+       0.308658; 0.461940; 0.831470;,
+       0.212608; 0.318190; 0.923880;,
+       0.212607; 0.513280; 0.831470;,
+       0.270598; 0.653281; 0.707107;,
+       0.392847; 0.587938; 0.707107;,
+       0.308658; 0.461940; 0.831470;,
+       0.270598; 0.653281; 0.707107;,
+       0.318190; 0.768178; 0.555570;,
+       0.461940; 0.691342; 0.555570;,
+       0.392847; 0.587938; 0.707107;,
+       0.318190; 0.768178; 0.555570;,
+       0.353553; 0.853553; 0.382683;,
+       0.513280; 0.768178; 0.382683;,
+       0.461940; 0.691342; 0.555570;,
+       0.353553; 0.853553; 0.382683;,
+       0.375330; 0.906127; 0.195090;,
+       0.544895; 0.815493; 0.195090;,
+       0.513280; 0.768178; 0.382683;,
+       0.375330; 0.906127; 0.195090;,
+       0.382683; 0.923879; 0.000000;,
+       0.555570; 0.831470; 0.000000;,
+       0.544895; 0.815493; 0.195090;,
+       0.382683; 0.923879; 0.000000;,
+       0.375330; 0.906127;-0.195090;,
+       0.544895; 0.815493;-0.195090;,
+       0.555570; 0.831470; 0.000000;,
+       0.375330; 0.906127;-0.195090;,
+       0.353553; 0.853553;-0.382683;,
+       0.513280; 0.768178;-0.382683;,
+       0.544895; 0.815493;-0.195090;,
+       0.353553; 0.853553;-0.382683;,
+       0.318190; 0.768178;-0.555570;,
+       0.461940; 0.691342;-0.555570;,
+       0.513280; 0.768178;-0.382683;,
+       0.318190; 0.768178;-0.555570;,
+       0.270598; 0.653281;-0.707107;,
+       0.392847; 0.587938;-0.707107;,
+       0.461940; 0.691342;-0.555570;,
+       0.270598; 0.653281;-0.707107;,
+       0.212607; 0.513280;-0.831470;,
+       0.308658; 0.461940;-0.831470;,
+       0.392847; 0.587938;-0.707107;,
+       0.212607; 0.513280;-0.831470;,
+       0.146447; 0.353553;-0.923880;,
+       0.212607; 0.318190;-0.923880;,
+       0.308658; 0.461940;-0.831470;,
+       0.146447; 0.353553;-0.923880;,
+       0.074658; 0.180240;-0.980785;,
+       0.108386; 0.162211;-0.980785;,
+       0.212607; 0.318190;-0.923880;,
+       0.074658; 0.180240;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.108386; 0.162211;-0.980785;,
+       0.038060; 0.191341;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.074658; 0.180240;-0.980785;,
+       0.074658; 0.375330;-0.923880;,
+       0.038060; 0.191341;-0.980785;,
+       0.074658; 0.180240;-0.980785;,
+       0.146447; 0.353553;-0.923880;,
+       0.108386; 0.544895;-0.831470;,
+       0.074658; 0.375330;-0.923880;,
+       0.146447; 0.353553;-0.923880;,
+       0.212607; 0.513280;-0.831470;,
+       0.137950; 0.693520;-0.707107;,
+       0.108386; 0.544895;-0.831470;,
+       0.212607; 0.513280;-0.831470;,
+       0.270598; 0.653281;-0.707107;,
+       0.162212; 0.815493;-0.555570;,
+       0.137950; 0.693520;-0.707107;,
+       0.270598; 0.653281;-0.707107;,
+       0.318190; 0.768178;-0.555570;,
+       0.180240; 0.906127;-0.382683;,
+       0.162212; 0.815493;-0.555570;,
+       0.318190; 0.768178;-0.555570;,
+       0.353553; 0.853553;-0.382683;,
+       0.191342; 0.961940;-0.195090;,
+       0.180240; 0.906127;-0.382683;,
+       0.353553; 0.853553;-0.382683;,
+       0.375330; 0.906127;-0.195090;,
+       0.195090; 0.980785; 0.000000;,
+       0.191342; 0.961940;-0.195090;,
+       0.375330; 0.906127;-0.195090;,
+       0.382683; 0.923879; 0.000000;,
+       0.191342; 0.961940; 0.195090;,
+       0.195090; 0.980785; 0.000000;,
+       0.382683; 0.923879; 0.000000;,
+       0.375330; 0.906127; 0.195090;,
+       0.180240; 0.906127; 0.382683;,
+       0.191342; 0.961940; 0.195090;,
+       0.375330; 0.906127; 0.195090;,
+       0.353553; 0.853553; 0.382683;,
+       0.162212; 0.815493; 0.555570;,
+       0.180240; 0.906127; 0.382683;,
+       0.353553; 0.853553; 0.382683;,
+       0.318190; 0.768178; 0.555570;,
+       0.137950; 0.693520; 0.707107;,
+       0.162212; 0.815493; 0.555570;,
+       0.318190; 0.768178; 0.555570;,
+       0.270598; 0.653281; 0.707107;,
+       0.108386; 0.544895; 0.831470;,
+       0.137950; 0.693520; 0.707107;,
+       0.270598; 0.653281; 0.707107;,
+       0.212607; 0.513280; 0.831470;,
+       0.074658; 0.375330; 0.923880;,
+       0.108386; 0.544895; 0.831470;,
+       0.212607; 0.513280; 0.831470;,
+       0.146447; 0.353553; 0.923880;,
+       0.038060; 0.191342; 0.980785;,
+       0.074658; 0.375330; 0.923880;,
+       0.146447; 0.353553; 0.923880;,
+       0.074658; 0.180240; 0.980785;,
+       0.038060; 0.191342; 0.980785;,
+       0.074658; 0.180240; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.000000; 0.195090; 0.980785;,
+       0.038060; 0.191342; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.000000; 0.195090; 0.980785;,
+      -0.000000; 0.382683; 0.923880;,
+       0.074658; 0.375330; 0.923880;,
+       0.038060; 0.191342; 0.980785;,
+      -0.000000; 0.382683; 0.923880;,
+      -0.000000; 0.555570; 0.831470;,
+       0.108386; 0.544895; 0.831470;,
+       0.074658; 0.375330; 0.923880;,
+      -0.000000; 0.555570; 0.831470;,
+       0.000000; 0.707107; 0.707107;,
+       0.137950; 0.693520; 0.707107;,
+       0.108386; 0.544895; 0.831470;,
+       0.000000; 0.707107; 0.707107;,
+      -0.000000; 0.831469; 0.555570;,
+       0.162212; 0.815493; 0.555570;,
+       0.137950; 0.693520; 0.707107;,
+      -0.000000; 0.831469; 0.555570;,
+       0.000000; 0.923879; 0.382683;,
+       0.180240; 0.906127; 0.382683;,
+       0.162212; 0.815493; 0.555570;,
+       0.000000; 0.923879; 0.382683;,
+      -0.000000; 0.980785; 0.195090;,
+       0.191342; 0.961940; 0.195090;,
+       0.180240; 0.906127; 0.382683;,
+      -0.000000; 0.980785; 0.195090;,
+      -0.000000; 1.000000; 0.000000;,
+       0.195090; 0.980785; 0.000000;,
+       0.191342; 0.961940; 0.195090;,
+      -0.000000; 1.000000; 0.000000;,
+      -0.000000; 0.980785;-0.195090;,
+       0.191342; 0.961940;-0.195090;,
+       0.195090; 0.980785; 0.000000;,
+      -0.000000; 0.980785;-0.195090;,
+      -0.000000; 0.923879;-0.382683;,
+       0.180240; 0.906127;-0.382683;,
+       0.191342; 0.961940;-0.195090;,
+      -0.000000; 0.923879;-0.382683;,
+      -0.000000; 0.831469;-0.555570;,
+       0.162212; 0.815493;-0.555570;,
+       0.180240; 0.906127;-0.382683;,
+      -0.000000; 0.831469;-0.555570;,
+       0.000000; 0.707107;-0.707107;,
+       0.137950; 0.693520;-0.707107;,
+       0.162212; 0.815493;-0.555570;,
+       0.000000; 0.707107;-0.707107;,
+      -0.000000; 0.555570;-0.831470;,
+       0.108386; 0.544895;-0.831470;,
+       0.137950; 0.693520;-0.707107;,
+      -0.000000; 0.555570;-0.831470;,
+      -0.000000; 0.382683;-0.923880;,
+       0.074658; 0.375330;-0.923880;,
+       0.108386; 0.544895;-0.831470;,
+      -0.000000; 0.382683;-0.923880;,
+      -0.000000; 0.195090;-0.980785;,
+       0.038060; 0.191341;-0.980785;,
+       0.074658; 0.375330;-0.923880;,
+      -0.000000; 0.195090;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.038060; 0.191341;-0.980785;,
+      -0.038060; 0.191341;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.000000; 0.195090;-0.980785;,
+      -0.074658; 0.375330;-0.923880;,
+      -0.038060; 0.191341;-0.980785;,
+      -0.000000; 0.195090;-0.980785;,
+      -0.000000; 0.382683;-0.923880;,
+      -0.108386; 0.544895;-0.831470;,
+      -0.074658; 0.375330;-0.923880;,
+      -0.000000; 0.382683;-0.923880;,
+      -0.000000; 0.555570;-0.831470;,
+      -0.137950; 0.693520;-0.707107;,
+      -0.108386; 0.544895;-0.831470;,
+      -0.000000; 0.555570;-0.831470;,
+       0.000000; 0.707107;-0.707107;,
+      -0.162212; 0.815493;-0.555570;,
+      -0.137950; 0.693520;-0.707107;,
+       0.000000; 0.707107;-0.707107;,
+      -0.000000; 0.831469;-0.555570;,
+      -0.180240; 0.906127;-0.382683;,
+      -0.162212; 0.815493;-0.555570;,
+      -0.000000; 0.831469;-0.555570;,
+      -0.000000; 0.923879;-0.382683;,
+      -0.191342; 0.961940;-0.195090;,
+      -0.180240; 0.906127;-0.382683;,
+      -0.000000; 0.923879;-0.382683;,
+      -0.000000; 0.980785;-0.195090;,
+      -0.195090; 0.980785; 0.000000;,
+      -0.191342; 0.961940;-0.195090;,
+      -0.000000; 0.980785;-0.195090;,
+      -0.000000; 1.000000; 0.000000;,
+      -0.191342; 0.961940; 0.195090;,
+      -0.195090; 0.980785; 0.000000;,
+      -0.000000; 1.000000; 0.000000;,
+      -0.000000; 0.980785; 0.195090;,
+      -0.180240; 0.906127; 0.382683;,
+      -0.191342; 0.961940; 0.195090;,
+      -0.000000; 0.980785; 0.195090;,
+       0.000000; 0.923879; 0.382683;,
+      -0.162212; 0.815493; 0.555570;,
+      -0.180240; 0.906127; 0.382683;,
+       0.000000; 0.923879; 0.382683;,
+      -0.000000; 0.831469; 0.555570;,
+      -0.137950; 0.693520; 0.707107;,
+      -0.162212; 0.815493; 0.555570;,
+      -0.000000; 0.831469; 0.555570;,
+       0.000000; 0.707107; 0.707107;,
+      -0.108386; 0.544895; 0.831470;,
+      -0.137950; 0.693520; 0.707107;,
+       0.000000; 0.707107; 0.707107;,
+      -0.000000; 0.555570; 0.831470;,
+      -0.074658; 0.375330; 0.923880;,
+      -0.108386; 0.544895; 0.831470;,
+      -0.000000; 0.555570; 0.831470;,
+      -0.000000; 0.382683; 0.923880;,
+      -0.038060; 0.191342; 0.980785;,
+      -0.074658; 0.375330; 0.923880;,
+      -0.000000; 0.382683; 0.923880;,
+      -0.000000; 0.195090; 0.980785;,
+      -0.038060; 0.191342; 0.980785;,
+      -0.000000; 0.195090; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.074658; 0.180240; 0.980785;,
+      -0.038060; 0.191342; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.074658; 0.180240; 0.980785;,
+      -0.146447; 0.353553; 0.923880;,
+      -0.074658; 0.375330; 0.923880;,
+      -0.038060; 0.191342; 0.980785;,
+      -0.146447; 0.353553; 0.923880;,
+      -0.212608; 0.513280; 0.831470;,
+      -0.108386; 0.544895; 0.831470;,
+      -0.074658; 0.375330; 0.923880;,
+      -0.212608; 0.513280; 0.831470;,
+      -0.270598; 0.653281; 0.707107;,
+      -0.137950; 0.693520; 0.707107;,
+      -0.108386; 0.544895; 0.831470;,
+      -0.270598; 0.653281; 0.707107;,
+      -0.318190; 0.768178; 0.555570;,
+      -0.162212; 0.815493; 0.555570;,
+      -0.137950; 0.693520; 0.707107;,
+      -0.318190; 0.768178; 0.555570;,
+      -0.353553; 0.853553; 0.382683;,
+      -0.180240; 0.906127; 0.382683;,
+      -0.162212; 0.815493; 0.555570;,
+      -0.353553; 0.853553; 0.382683;,
+      -0.375330; 0.906127; 0.195090;,
+      -0.191342; 0.961940; 0.195090;,
+      -0.180240; 0.906127; 0.382683;,
+      -0.375330; 0.906127; 0.195090;,
+      -0.382683; 0.923879; 0.000000;,
+      -0.195090; 0.980785; 0.000000;,
+      -0.191342; 0.961940; 0.195090;,
+      -0.382683; 0.923879; 0.000000;,
+      -0.375330; 0.906127;-0.195090;,
+      -0.191342; 0.961940;-0.195090;,
+      -0.195090; 0.980785; 0.000000;,
+      -0.375330; 0.906127;-0.195090;,
+      -0.353553; 0.853553;-0.382683;,
+      -0.180240; 0.906127;-0.382683;,
+      -0.191342; 0.961940;-0.195090;,
+      -0.353553; 0.853553;-0.382683;,
+      -0.318190; 0.768178;-0.555570;,
+      -0.162212; 0.815493;-0.555570;,
+      -0.180240; 0.906127;-0.382683;,
+      -0.318190; 0.768178;-0.555570;,
+      -0.270598; 0.653281;-0.707107;,
+      -0.137950; 0.693520;-0.707107;,
+      -0.162212; 0.815493;-0.555570;,
+      -0.270598; 0.653281;-0.707107;,
+      -0.212607; 0.513280;-0.831470;,
+      -0.108386; 0.544895;-0.831470;,
+      -0.137950; 0.693520;-0.707107;,
+      -0.212607; 0.513280;-0.831470;,
+      -0.146447; 0.353553;-0.923880;,
+      -0.074658; 0.375330;-0.923880;,
+      -0.108386; 0.544895;-0.831470;,
+      -0.146447; 0.353553;-0.923880;,
+      -0.074658; 0.180240;-0.980785;,
+      -0.038060; 0.191341;-0.980785;,
+      -0.074658; 0.375330;-0.923880;,
+      -0.074658; 0.180240;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.038060; 0.191341;-0.980785;,
+      -0.108386; 0.162211;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.074658; 0.180240;-0.980785;,
+      -0.212607; 0.318189;-0.923880;,
+      -0.108386; 0.162211;-0.980785;,
+      -0.074658; 0.180240;-0.980785;,
+      -0.146447; 0.353553;-0.923880;,
+      -0.308658; 0.461940;-0.831470;,
+      -0.212607; 0.318189;-0.923880;,
+      -0.146447; 0.353553;-0.923880;,
+      -0.212607; 0.513280;-0.831470;,
+      -0.392847; 0.587938;-0.707107;,
+      -0.308658; 0.461940;-0.831470;,
+      -0.212607; 0.513280;-0.831470;,
+      -0.270598; 0.653281;-0.707107;,
+      -0.461940; 0.691342;-0.555570;,
+      -0.392847; 0.587938;-0.707107;,
+      -0.270598; 0.653281;-0.707107;,
+      -0.318190; 0.768178;-0.555570;,
+      -0.513280; 0.768178;-0.382683;,
+      -0.461940; 0.691342;-0.555570;,
+      -0.318190; 0.768178;-0.555570;,
+      -0.353553; 0.853553;-0.382683;,
+      -0.544895; 0.815493;-0.195090;,
+      -0.513280; 0.768178;-0.382683;,
+      -0.353553; 0.853553;-0.382683;,
+      -0.375330; 0.906127;-0.195090;,
+      -0.555570; 0.831469; 0.000000;,
+      -0.544895; 0.815493;-0.195090;,
+      -0.375330; 0.906127;-0.195090;,
+      -0.382683; 0.923879; 0.000000;,
+      -0.544895; 0.815493; 0.195090;,
+      -0.555570; 0.831469; 0.000000;,
+      -0.382683; 0.923879; 0.000000;,
+      -0.375330; 0.906127; 0.195090;,
+      -0.513280; 0.768178; 0.382683;,
+      -0.544895; 0.815493; 0.195090;,
+      -0.375330; 0.906127; 0.195090;,
+      -0.353553; 0.853553; 0.382683;,
+      -0.461940; 0.691342; 0.555570;,
+      -0.513280; 0.768178; 0.382683;,
+      -0.353553; 0.853553; 0.382683;,
+      -0.318190; 0.768178; 0.555570;,
+      -0.392847; 0.587938; 0.707107;,
+      -0.461940; 0.691342; 0.555570;,
+      -0.318190; 0.768178; 0.555570;,
+      -0.270598; 0.653281; 0.707107;,
+      -0.308658; 0.461940; 0.831470;,
+      -0.392847; 0.587938; 0.707107;,
+      -0.270598; 0.653281; 0.707107;,
+      -0.212608; 0.513280; 0.831470;,
+      -0.212608; 0.318190; 0.923880;,
+      -0.308658; 0.461940; 0.831470;,
+      -0.212608; 0.513280; 0.831470;,
+      -0.146447; 0.353553; 0.923880;,
+      -0.108386; 0.162212; 0.980785;,
+      -0.212608; 0.318190; 0.923880;,
+      -0.146447; 0.353553; 0.923880;,
+      -0.074658; 0.180240; 0.980785;,
+      -0.108386; 0.162212; 0.980785;,
+      -0.074658; 0.180240; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.137950; 0.137950; 0.980785;,
+      -0.108386; 0.162212; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.137950; 0.137950; 0.980785;,
+      -0.270598; 0.270598; 0.923880;,
+      -0.212608; 0.318190; 0.923880;,
+      -0.108386; 0.162212; 0.980785;,
+      -0.270598; 0.270598; 0.923880;,
+      -0.392847; 0.392847; 0.831470;,
+      -0.308658; 0.461940; 0.831470;,
+      -0.212608; 0.318190; 0.923880;,
+      -0.392847; 0.392847; 0.831470;,
+      -0.500000; 0.500000; 0.707107;,
+      -0.392847; 0.587938; 0.707107;,
+      -0.308658; 0.461940; 0.831470;,
+      -0.500000; 0.500000; 0.707107;,
+      -0.587938; 0.587938; 0.555570;,
+      -0.461940; 0.691342; 0.555570;,
+      -0.392847; 0.587938; 0.707107;,
+      -0.587938; 0.587938; 0.555570;,
+      -0.653281; 0.653281; 0.382683;,
+      -0.513280; 0.768178; 0.382683;,
+      -0.461940; 0.691342; 0.555570;,
+      -0.653281; 0.653281; 0.382683;,
+      -0.693520; 0.693520; 0.195090;,
+      -0.544895; 0.815493; 0.195090;,
+      -0.513280; 0.768178; 0.382683;,
+      -0.693520; 0.693520; 0.195090;,
+      -0.707107; 0.707106; 0.000000;,
+      -0.555570; 0.831469; 0.000000;,
+      -0.544895; 0.815493; 0.195090;,
+      -0.707107; 0.707106; 0.000000;,
+      -0.693520; 0.693520;-0.195090;,
+      -0.544895; 0.815493;-0.195090;,
+      -0.555570; 0.831469; 0.000000;,
+      -0.693520; 0.693520;-0.195090;,
+      -0.653281; 0.653281;-0.382683;,
+      -0.513280; 0.768178;-0.382683;,
+      -0.544895; 0.815493;-0.195090;,
+      -0.653281; 0.653281;-0.382683;,
+      -0.587938; 0.587938;-0.555570;,
+      -0.461940; 0.691342;-0.555570;,
+      -0.513280; 0.768178;-0.382683;,
+      -0.587938; 0.587938;-0.555570;,
+      -0.500000; 0.500000;-0.707107;,
+      -0.392847; 0.587938;-0.707107;,
+      -0.461940; 0.691342;-0.555570;,
+      -0.500000; 0.500000;-0.707107;,
+      -0.392847; 0.392847;-0.831470;,
+      -0.308658; 0.461940;-0.831470;,
+      -0.392847; 0.587938;-0.707107;,
+      -0.392847; 0.392847;-0.831470;,
+      -0.270598; 0.270598;-0.923880;,
+      -0.212607; 0.318189;-0.923880;,
+      -0.308658; 0.461940;-0.831470;,
+      -0.270598; 0.270598;-0.923880;,
+      -0.137949; 0.137949;-0.980785;,
+      -0.108386; 0.162211;-0.980785;,
+      -0.212607; 0.318189;-0.923880;,
+      -0.137949; 0.137949;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.108386; 0.162211;-0.980785;,
+      -0.162211; 0.108386;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.137949; 0.137949;-0.980785;,
+      -0.318189; 0.212607;-0.923880;,
+      -0.162211; 0.108386;-0.980785;,
+      -0.137949; 0.137949;-0.980785;,
+      -0.270598; 0.270598;-0.923880;,
+      -0.461940; 0.308658;-0.831470;,
+      -0.318189; 0.212607;-0.923880;,
+      -0.270598; 0.270598;-0.923880;,
+      -0.392847; 0.392847;-0.831470;,
+      -0.587938; 0.392847;-0.707107;,
+      -0.461940; 0.308658;-0.831470;,
+      -0.392847; 0.392847;-0.831470;,
+      -0.500000; 0.500000;-0.707107;,
+      -0.691342; 0.461940;-0.555570;,
+      -0.587938; 0.392847;-0.707107;,
+      -0.500000; 0.500000;-0.707107;,
+      -0.587938; 0.587938;-0.555570;,
+      -0.768178; 0.513280;-0.382683;,
+      -0.691342; 0.461940;-0.555570;,
+      -0.587938; 0.587938;-0.555570;,
+      -0.653281; 0.653281;-0.382683;,
+      -0.815493; 0.544895;-0.195090;,
+      -0.768178; 0.513280;-0.382683;,
+      -0.653281; 0.653281;-0.382683;,
+      -0.693520; 0.693520;-0.195090;,
+      -0.831469; 0.555570; 0.000000;,
+      -0.815493; 0.544895;-0.195090;,
+      -0.693520; 0.693520;-0.195090;,
+      -0.707107; 0.707106; 0.000000;,
+      -0.815493; 0.544895; 0.195090;,
+      -0.831469; 0.555570; 0.000000;,
+      -0.707107; 0.707106; 0.000000;,
+      -0.693520; 0.693520; 0.195090;,
+      -0.768178; 0.513280; 0.382683;,
+      -0.815493; 0.544895; 0.195090;,
+      -0.693520; 0.693520; 0.195090;,
+      -0.653281; 0.653281; 0.382683;,
+      -0.691342; 0.461940; 0.555570;,
+      -0.768178; 0.513280; 0.382683;,
+      -0.653281; 0.653281; 0.382683;,
+      -0.587938; 0.587938; 0.555570;,
+      -0.587938; 0.392847; 0.707107;,
+      -0.691342; 0.461940; 0.555570;,
+      -0.587938; 0.587938; 0.555570;,
+      -0.500000; 0.500000; 0.707107;,
+      -0.461940; 0.308658; 0.831470;,
+      -0.587938; 0.392847; 0.707107;,
+      -0.500000; 0.500000; 0.707107;,
+      -0.392847; 0.392847; 0.831470;,
+      -0.318190; 0.212607; 0.923880;,
+      -0.461940; 0.308658; 0.831470;,
+      -0.392847; 0.392847; 0.831470;,
+      -0.270598; 0.270598; 0.923880;,
+      -0.162212; 0.108386; 0.980785;,
+      -0.318190; 0.212607; 0.923880;,
+      -0.270598; 0.270598; 0.923880;,
+      -0.137950; 0.137950; 0.980785;,
+      -0.162212; 0.108386; 0.980785;,
+      -0.137950; 0.137950; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.180240; 0.074658; 0.980785;,
+      -0.162212; 0.108386; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.180240; 0.074658; 0.980785;,
+      -0.353553; 0.146447; 0.923880;,
+      -0.318190; 0.212607; 0.923880;,
+      -0.162212; 0.108386; 0.980785;,
+      -0.353553; 0.146447; 0.923880;,
+      -0.513280; 0.212607; 0.831470;,
+      -0.461940; 0.308658; 0.831470;,
+      -0.318190; 0.212607; 0.923880;,
+      -0.513280; 0.212607; 0.831470;,
+      -0.653281; 0.270598; 0.707107;,
+      -0.587938; 0.392847; 0.707107;,
+      -0.461940; 0.308658; 0.831470;,
+      -0.653281; 0.270598; 0.707107;,
+      -0.768178; 0.318189; 0.555570;,
+      -0.691342; 0.461940; 0.555570;,
+      -0.587938; 0.392847; 0.707107;,
+      -0.768178; 0.318189; 0.555570;,
+      -0.853553; 0.353553; 0.382683;,
+      -0.768178; 0.513280; 0.382683;,
+      -0.691342; 0.461940; 0.555570;,
+      -0.853553; 0.353553; 0.382683;,
+      -0.906127; 0.375330; 0.195090;,
+      -0.815493; 0.544895; 0.195090;,
+      -0.768178; 0.513280; 0.382683;,
+      -0.906127; 0.375330; 0.195090;,
+      -0.923879; 0.382683; 0.000000;,
+      -0.831469; 0.555570; 0.000000;,
+      -0.815493; 0.544895; 0.195090;,
+      -0.923879; 0.382683; 0.000000;,
+      -0.906127; 0.375330;-0.195090;,
+      -0.815493; 0.544895;-0.195090;,
+      -0.831469; 0.555570; 0.000000;,
+      -0.906127; 0.375330;-0.195090;,
+      -0.853553; 0.353553;-0.382683;,
+      -0.768178; 0.513280;-0.382683;,
+      -0.815493; 0.544895;-0.195090;,
+      -0.853553; 0.353553;-0.382683;,
+      -0.768178; 0.318189;-0.555570;,
+      -0.691342; 0.461940;-0.555570;,
+      -0.768178; 0.513280;-0.382683;,
+      -0.768178; 0.318189;-0.555570;,
+      -0.653281; 0.270598;-0.707107;,
+      -0.587938; 0.392847;-0.707107;,
+      -0.691342; 0.461940;-0.555570;,
+      -0.653281; 0.270598;-0.707107;,
+      -0.513280; 0.212607;-0.831470;,
+      -0.461940; 0.308658;-0.831470;,
+      -0.587938; 0.392847;-0.707107;,
+      -0.513280; 0.212607;-0.831470;,
+      -0.353553; 0.146447;-0.923880;,
+      -0.318189; 0.212607;-0.923880;,
+      -0.461940; 0.308658;-0.831470;,
+      -0.353553; 0.146447;-0.923880;,
+      -0.180240; 0.074658;-0.980785;,
+      -0.162211; 0.108386;-0.980785;,
+      -0.318189; 0.212607;-0.923880;,
+      -0.180240; 0.074658;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.162211; 0.108386;-0.980785;,
+      -0.191341; 0.038060;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.180240; 0.074658;-0.980785;,
+      -0.375330; 0.074658;-0.923880;,
+      -0.191341; 0.038060;-0.980785;,
+      -0.180240; 0.074658;-0.980785;,
+      -0.353553; 0.146447;-0.923880;,
+      -0.544895; 0.108386;-0.831470;,
+      -0.375330; 0.074658;-0.923880;,
+      -0.353553; 0.146447;-0.923880;,
+      -0.513280; 0.212607;-0.831470;,
+      -0.693520; 0.137950;-0.707107;,
+      -0.544895; 0.108386;-0.831470;,
+      -0.513280; 0.212607;-0.831470;,
+      -0.653281; 0.270598;-0.707107;,
+      -0.815493; 0.162212;-0.555570;,
+      -0.693520; 0.137950;-0.707107;,
+      -0.653281; 0.270598;-0.707107;,
+      -0.768178; 0.318189;-0.555570;,
+      -0.906127; 0.180240;-0.382683;,
+      -0.815493; 0.162212;-0.555570;,
+      -0.768178; 0.318189;-0.555570;,
+      -0.853553; 0.353553;-0.382683;,
+      -0.961939; 0.191342;-0.195090;,
+      -0.906127; 0.180240;-0.382683;,
+      -0.853553; 0.353553;-0.382683;,
+      -0.906127; 0.375330;-0.195090;,
+      -0.980785; 0.195090; 0.000000;,
+      -0.961939; 0.191342;-0.195090;,
+      -0.906127; 0.375330;-0.195090;,
+      -0.923879; 0.382683; 0.000000;,
+      -0.961939; 0.191342; 0.195090;,
+      -0.980785; 0.195090; 0.000000;,
+      -0.923879; 0.382683; 0.000000;,
+      -0.906127; 0.375330; 0.195090;,
+      -0.906127; 0.180240; 0.382683;,
+      -0.961939; 0.191342; 0.195090;,
+      -0.906127; 0.375330; 0.195090;,
+      -0.853553; 0.353553; 0.382683;,
+      -0.815493; 0.162212; 0.555570;,
+      -0.906127; 0.180240; 0.382683;,
+      -0.853553; 0.353553; 0.382683;,
+      -0.768178; 0.318189; 0.555570;,
+      -0.693520; 0.137950; 0.707107;,
+      -0.815493; 0.162212; 0.555570;,
+      -0.768178; 0.318189; 0.555570;,
+      -0.653281; 0.270598; 0.707107;,
+      -0.544895; 0.108386; 0.831470;,
+      -0.693520; 0.137950; 0.707107;,
+      -0.653281; 0.270598; 0.707107;,
+      -0.513280; 0.212607; 0.831470;,
+      -0.375330; 0.074658; 0.923880;,
+      -0.544895; 0.108386; 0.831470;,
+      -0.513280; 0.212607; 0.831470;,
+      -0.353553; 0.146447; 0.923880;,
+      -0.191342; 0.038060; 0.980785;,
+      -0.375330; 0.074658; 0.923880;,
+      -0.353553; 0.146447; 0.923880;,
+      -0.180240; 0.074658; 0.980785;,
+      -0.191342; 0.038060; 0.980785;,
+      -0.180240; 0.074658; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.195090;-0.000000; 0.980785;,
+      -0.191342; 0.038060; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.195090;-0.000000; 0.980785;,
+      -0.382683;-0.000000; 0.923880;,
+      -0.375330; 0.074658; 0.923880;,
+      -0.191342; 0.038060; 0.980785;,
+      -0.382683;-0.000000; 0.923880;,
+      -0.555570;-0.000000; 0.831470;,
+      -0.544895; 0.108386; 0.831470;,
+      -0.375330; 0.074658; 0.923880;,
+      -0.555570;-0.000000; 0.831470;,
+      -0.707107;-0.000000; 0.707107;,
+      -0.693520; 0.137950; 0.707107;,
+      -0.544895; 0.108386; 0.831470;,
+      -0.707107;-0.000000; 0.707107;,
+      -0.831469;-0.000000; 0.555570;,
+      -0.815493; 0.162212; 0.555570;,
+      -0.693520; 0.137950; 0.707107;,
+      -0.831469;-0.000000; 0.555570;,
+      -0.923879; 0.000000; 0.382683;,
+      -0.906127; 0.180240; 0.382683;,
+      -0.815493; 0.162212; 0.555570;,
+      -0.923879; 0.000000; 0.382683;,
+      -0.980785;-0.000000; 0.195090;,
+      -0.961939; 0.191342; 0.195090;,
+      -0.906127; 0.180240; 0.382683;,
+      -0.980785;-0.000000; 0.195090;,
+      -0.999999;-0.000000; 0.000000;,
+      -0.980785; 0.195090; 0.000000;,
+      -0.961939; 0.191342; 0.195090;,
+      -0.999999;-0.000000; 0.000000;,
+      -0.980785;-0.000000;-0.195090;,
+      -0.961939; 0.191342;-0.195090;,
+      -0.980785; 0.195090; 0.000000;,
+      -0.980785;-0.000000;-0.195090;,
+      -0.923879;-0.000000;-0.382683;,
+      -0.906127; 0.180240;-0.382683;,
+      -0.961939; 0.191342;-0.195090;,
+      -0.923879;-0.000000;-0.382683;,
+      -0.831469;-0.000000;-0.555570;,
+      -0.815493; 0.162212;-0.555570;,
+      -0.906127; 0.180240;-0.382683;,
+      -0.831469;-0.000000;-0.555570;,
+      -0.707107;-0.000000;-0.707107;,
+      -0.693520; 0.137950;-0.707107;,
+      -0.815493; 0.162212;-0.555570;,
+      -0.707107;-0.000000;-0.707107;,
+      -0.555570;-0.000000;-0.831470;,
+      -0.544895; 0.108386;-0.831470;,
+      -0.693520; 0.137950;-0.707107;,
+      -0.555570;-0.000000;-0.831470;,
+      -0.382683;-0.000000;-0.923880;,
+      -0.375330; 0.074658;-0.923880;,
+      -0.544895; 0.108386;-0.831470;,
+      -0.382683;-0.000000;-0.923880;,
+      -0.195090;-0.000000;-0.980785;,
+      -0.191341; 0.038060;-0.980785;,
+      -0.375330; 0.074658;-0.923880;,
+      -0.195090;-0.000000;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.191341; 0.038060;-0.980785;,
+      -0.191341;-0.038060;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.195090;-0.000000;-0.980785;,
+      -0.375330;-0.074658;-0.923880;,
+      -0.191341;-0.038060;-0.980785;,
+      -0.195090;-0.000000;-0.980785;,
+      -0.382683;-0.000000;-0.923880;,
+      -0.544895;-0.108386;-0.831470;,
+      -0.375330;-0.074658;-0.923880;,
+      -0.382683;-0.000000;-0.923880;,
+      -0.555570;-0.000000;-0.831470;,
+      -0.693520;-0.137950;-0.707107;,
+      -0.544895;-0.108386;-0.831470;,
+      -0.555570;-0.000000;-0.831470;,
+      -0.707107;-0.000000;-0.707107;,
+      -0.815493;-0.162212;-0.555570;,
+      -0.693520;-0.137950;-0.707107;,
+      -0.707107;-0.000000;-0.707107;,
+      -0.831469;-0.000000;-0.555570;,
+      -0.906127;-0.180240;-0.382683;,
+      -0.815493;-0.162212;-0.555570;,
+      -0.831469;-0.000000;-0.555570;,
+      -0.923879;-0.000000;-0.382683;,
+      -0.961939;-0.191342;-0.195090;,
+      -0.906127;-0.180240;-0.382683;,
+      -0.923879;-0.000000;-0.382683;,
+      -0.980785;-0.000000;-0.195090;,
+      -0.980785;-0.195091; 0.000000;,
+      -0.961939;-0.191342;-0.195090;,
+      -0.980785;-0.000000;-0.195090;,
+      -0.999999;-0.000000; 0.000000;,
+      -0.961939;-0.191342; 0.195090;,
+      -0.980785;-0.195091; 0.000000;,
+      -0.999999;-0.000000; 0.000000;,
+      -0.980785;-0.000000; 0.195090;,
+      -0.906127;-0.180240; 0.382683;,
+      -0.961939;-0.191342; 0.195090;,
+      -0.980785;-0.000000; 0.195090;,
+      -0.923879; 0.000000; 0.382683;,
+      -0.815493;-0.162212; 0.555570;,
+      -0.906127;-0.180240; 0.382683;,
+      -0.923879; 0.000000; 0.382683;,
+      -0.831469;-0.000000; 0.555570;,
+      -0.693520;-0.137950; 0.707107;,
+      -0.815493;-0.162212; 0.555570;,
+      -0.831469;-0.000000; 0.555570;,
+      -0.707107;-0.000000; 0.707107;,
+      -0.544895;-0.108386; 0.831470;,
+      -0.693520;-0.137950; 0.707107;,
+      -0.707107;-0.000000; 0.707107;,
+      -0.555570;-0.000000; 0.831470;,
+      -0.375330;-0.074658; 0.923880;,
+      -0.544895;-0.108386; 0.831470;,
+      -0.555570;-0.000000; 0.831470;,
+      -0.382683;-0.000000; 0.923880;,
+      -0.191342;-0.038060; 0.980785;,
+      -0.375330;-0.074658; 0.923880;,
+      -0.382683;-0.000000; 0.923880;,
+      -0.195090;-0.000000; 0.980785;,
+      -0.191342;-0.038060; 0.980785;,
+      -0.195090;-0.000000; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.180240;-0.074658; 0.980785;,
+      -0.191342;-0.038060; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.180240;-0.074658; 0.980785;,
+      -0.353553;-0.146447; 0.923880;,
+      -0.375330;-0.074658; 0.923880;,
+      -0.191342;-0.038060; 0.980785;,
+      -0.353553;-0.146447; 0.923880;,
+      -0.513280;-0.212608; 0.831470;,
+      -0.544895;-0.108386; 0.831470;,
+      -0.375330;-0.074658; 0.923880;,
+      -0.513280;-0.212608; 0.831470;,
+      -0.653281;-0.270598; 0.707107;,
+      -0.693520;-0.137950; 0.707107;,
+      -0.544895;-0.108386; 0.831470;,
+      -0.653281;-0.270598; 0.707107;,
+      -0.768177;-0.318190; 0.555570;,
+      -0.815493;-0.162212; 0.555570;,
+      -0.693520;-0.137950; 0.707107;,
+      -0.768177;-0.318190; 0.555570;,
+      -0.853553;-0.353553; 0.382683;,
+      -0.906127;-0.180240; 0.382683;,
+      -0.815493;-0.162212; 0.555570;,
+      -0.853553;-0.353553; 0.382683;,
+      -0.906127;-0.375330; 0.195090;,
+      -0.961939;-0.191342; 0.195090;,
+      -0.906127;-0.180240; 0.382683;,
+      -0.906127;-0.375330; 0.195090;,
+      -0.923879;-0.382683; 0.000000;,
+      -0.980785;-0.195091; 0.000000;,
+      -0.961939;-0.191342; 0.195090;,
+      -0.923879;-0.382683; 0.000000;,
+      -0.906127;-0.375330;-0.195090;,
+      -0.961939;-0.191342;-0.195090;,
+      -0.980785;-0.195091; 0.000000;,
+      -0.906127;-0.375330;-0.195090;,
+      -0.853553;-0.353553;-0.382683;,
+      -0.906127;-0.180240;-0.382683;,
+      -0.961939;-0.191342;-0.195090;,
+      -0.853553;-0.353553;-0.382683;,
+      -0.768177;-0.318190;-0.555570;,
+      -0.815493;-0.162212;-0.555570;,
+      -0.906127;-0.180240;-0.382683;,
+      -0.768177;-0.318190;-0.555570;,
+      -0.653281;-0.270598;-0.707107;,
+      -0.693520;-0.137950;-0.707107;,
+      -0.815493;-0.162212;-0.555570;,
+      -0.653281;-0.270598;-0.707107;,
+      -0.513280;-0.212607;-0.831470;,
+      -0.544895;-0.108386;-0.831470;,
+      -0.693520;-0.137950;-0.707107;,
+      -0.513280;-0.212607;-0.831470;,
+      -0.353553;-0.146447;-0.923880;,
+      -0.375330;-0.074658;-0.923880;,
+      -0.544895;-0.108386;-0.831470;,
+      -0.353553;-0.146447;-0.923880;,
+      -0.180240;-0.074658;-0.980785;,
+      -0.191341;-0.038060;-0.980785;,
+      -0.375330;-0.074658;-0.923880;,
+      -0.180240;-0.074658;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.191341;-0.038060;-0.980785;,
+      -0.162211;-0.108386;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.180240;-0.074658;-0.980785;,
+      -0.318189;-0.212607;-0.923880;,
+      -0.162211;-0.108386;-0.980785;,
+      -0.180240;-0.074658;-0.980785;,
+      -0.353553;-0.146447;-0.923880;,
+      -0.461939;-0.308658;-0.831470;,
+      -0.318189;-0.212607;-0.923880;,
+      -0.353553;-0.146447;-0.923880;,
+      -0.513280;-0.212607;-0.831470;,
+      -0.587938;-0.392847;-0.707107;,
+      -0.461939;-0.308658;-0.831470;,
+      -0.513280;-0.212607;-0.831470;,
+      -0.653281;-0.270598;-0.707107;,
+      -0.691341;-0.461940;-0.555570;,
+      -0.587938;-0.392847;-0.707107;,
+      -0.653281;-0.270598;-0.707107;,
+      -0.768177;-0.318190;-0.555570;,
+      -0.768178;-0.513280;-0.382683;,
+      -0.691341;-0.461940;-0.555570;,
+      -0.768177;-0.318190;-0.555570;,
+      -0.853553;-0.353553;-0.382683;,
+      -0.815493;-0.544895;-0.195090;,
+      -0.768178;-0.513280;-0.382683;,
+      -0.853553;-0.353553;-0.382683;,
+      -0.906127;-0.375330;-0.195090;,
+      -0.831469;-0.555570; 0.000000;,
+      -0.815493;-0.544895;-0.195090;,
+      -0.906127;-0.375330;-0.195090;,
+      -0.923879;-0.382683; 0.000000;,
+      -0.815493;-0.544895; 0.195090;,
+      -0.831469;-0.555570; 0.000000;,
+      -0.923879;-0.382683; 0.000000;,
+      -0.906127;-0.375330; 0.195090;,
+      -0.768178;-0.513280; 0.382683;,
+      -0.815493;-0.544895; 0.195090;,
+      -0.906127;-0.375330; 0.195090;,
+      -0.853553;-0.353553; 0.382683;,
+      -0.691341;-0.461940; 0.555570;,
+      -0.768178;-0.513280; 0.382683;,
+      -0.853553;-0.353553; 0.382683;,
+      -0.768177;-0.318190; 0.555570;,
+      -0.587938;-0.392847; 0.707107;,
+      -0.691341;-0.461940; 0.555570;,
+      -0.768177;-0.318190; 0.555570;,
+      -0.653281;-0.270598; 0.707107;,
+      -0.461939;-0.308658; 0.831470;,
+      -0.587938;-0.392847; 0.707107;,
+      -0.653281;-0.270598; 0.707107;,
+      -0.513280;-0.212608; 0.831470;,
+      -0.318190;-0.212608; 0.923880;,
+      -0.461939;-0.308658; 0.831470;,
+      -0.513280;-0.212608; 0.831470;,
+      -0.353553;-0.146447; 0.923880;,
+      -0.162212;-0.108386; 0.980785;,
+      -0.318190;-0.212608; 0.923880;,
+      -0.353553;-0.146447; 0.923880;,
+      -0.180240;-0.074658; 0.980785;,
+      -0.162212;-0.108386; 0.980785;,
+      -0.180240;-0.074658; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.137950;-0.137950; 0.980785;,
+      -0.162212;-0.108386; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.137950;-0.137950; 0.980785;,
+      -0.270598;-0.270598; 0.923880;,
+      -0.318190;-0.212608; 0.923880;,
+      -0.162212;-0.108386; 0.980785;,
+      -0.270598;-0.270598; 0.923880;,
+      -0.392847;-0.392847; 0.831470;,
+      -0.461939;-0.308658; 0.831470;,
+      -0.318190;-0.212608; 0.923880;,
+      -0.392847;-0.392847; 0.831470;,
+      -0.500000;-0.500000; 0.707107;,
+      -0.587938;-0.392847; 0.707107;,
+      -0.461939;-0.308658; 0.831470;,
+      -0.500000;-0.500000; 0.707107;,
+      -0.587937;-0.587938; 0.555570;,
+      -0.691341;-0.461940; 0.555570;,
+      -0.587938;-0.392847; 0.707107;,
+      -0.587937;-0.587938; 0.555570;,
+      -0.653281;-0.653281; 0.382683;,
+      -0.768178;-0.513280; 0.382683;,
+      -0.691341;-0.461940; 0.555570;,
+      -0.653281;-0.653281; 0.382683;,
+      -0.693520;-0.693520; 0.195090;,
+      -0.815493;-0.544895; 0.195090;,
+      -0.768178;-0.513280; 0.382683;,
+      -0.693520;-0.693520; 0.195090;,
+      -0.707106;-0.707106; 0.000000;,
+      -0.831469;-0.555570; 0.000000;,
+      -0.815493;-0.544895; 0.195090;,
+      -0.707106;-0.707106; 0.000000;,
+      -0.693520;-0.693520;-0.195090;,
+      -0.815493;-0.544895;-0.195090;,
+      -0.831469;-0.555570; 0.000000;,
+      -0.693520;-0.693520;-0.195090;,
+      -0.653281;-0.653281;-0.382683;,
+      -0.768178;-0.513280;-0.382683;,
+      -0.815493;-0.544895;-0.195090;,
+      -0.653281;-0.653281;-0.382683;,
+      -0.587937;-0.587938;-0.555570;,
+      -0.691341;-0.461940;-0.555570;,
+      -0.768178;-0.513280;-0.382683;,
+      -0.587937;-0.587938;-0.555570;,
+      -0.500000;-0.500000;-0.707107;,
+      -0.587938;-0.392847;-0.707107;,
+      -0.691341;-0.461940;-0.555570;,
+      -0.500000;-0.500000;-0.707107;,
+      -0.392847;-0.392847;-0.831470;,
+      -0.461939;-0.308658;-0.831470;,
+      -0.587938;-0.392847;-0.707107;,
+      -0.392847;-0.392847;-0.831470;,
+      -0.270598;-0.270598;-0.923880;,
+      -0.318189;-0.212607;-0.923880;,
+      -0.461939;-0.308658;-0.831470;,
+      -0.270598;-0.270598;-0.923880;,
+      -0.137949;-0.137950;-0.980785;,
+      -0.162211;-0.108386;-0.980785;,
+      -0.318189;-0.212607;-0.923880;,
+      -0.137949;-0.137950;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.162211;-0.108386;-0.980785;,
+      -0.108386;-0.162211;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.137949;-0.137950;-0.980785;,
+      -0.212607;-0.318189;-0.923880;,
+      -0.108386;-0.162211;-0.980785;,
+      -0.137949;-0.137950;-0.980785;,
+      -0.270598;-0.270598;-0.923880;,
+      -0.308658;-0.461940;-0.831470;,
+      -0.212607;-0.318189;-0.923880;,
+      -0.270598;-0.270598;-0.923880;,
+      -0.392847;-0.392847;-0.831470;,
+      -0.392847;-0.587938;-0.707107;,
+      -0.308658;-0.461940;-0.831470;,
+      -0.392847;-0.392847;-0.831470;,
+      -0.500000;-0.500000;-0.707107;,
+      -0.461939;-0.691341;-0.555570;,
+      -0.392847;-0.587938;-0.707107;,
+      -0.500000;-0.500000;-0.707107;,
+      -0.587937;-0.587938;-0.555570;,
+      -0.513280;-0.768178;-0.382683;,
+      -0.461939;-0.691341;-0.555570;,
+      -0.587937;-0.587938;-0.555570;,
+      -0.653281;-0.653281;-0.382683;,
+      -0.544895;-0.815493;-0.195090;,
+      -0.513280;-0.768178;-0.382683;,
+      -0.653281;-0.653281;-0.382683;,
+      -0.693520;-0.693520;-0.195090;,
+      -0.555569;-0.831469; 0.000000;,
+      -0.544895;-0.815493;-0.195090;,
+      -0.693520;-0.693520;-0.195090;,
+      -0.707106;-0.707106; 0.000000;,
+      -0.544895;-0.815493; 0.195090;,
+      -0.555569;-0.831469; 0.000000;,
+      -0.707106;-0.707106; 0.000000;,
+      -0.693520;-0.693520; 0.195090;,
+      -0.513280;-0.768177; 0.382683;,
+      -0.544895;-0.815493; 0.195090;,
+      -0.693520;-0.693520; 0.195090;,
+      -0.653281;-0.653281; 0.382683;,
+      -0.461939;-0.691341; 0.555570;,
+      -0.513280;-0.768177; 0.382683;,
+      -0.653281;-0.653281; 0.382683;,
+      -0.587937;-0.587938; 0.555570;,
+      -0.392847;-0.587938; 0.707107;,
+      -0.461939;-0.691341; 0.555570;,
+      -0.587937;-0.587938; 0.555570;,
+      -0.500000;-0.500000; 0.707107;,
+      -0.308658;-0.461940; 0.831470;,
+      -0.392847;-0.587938; 0.707107;,
+      -0.500000;-0.500000; 0.707107;,
+      -0.392847;-0.392847; 0.831470;,
+      -0.212607;-0.318190; 0.923880;,
+      -0.308658;-0.461940; 0.831470;,
+      -0.392847;-0.392847; 0.831470;,
+      -0.270598;-0.270598; 0.923880;,
+      -0.108386;-0.162212; 0.980785;,
+      -0.212607;-0.318190; 0.923880;,
+      -0.270598;-0.270598; 0.923880;,
+      -0.137950;-0.137950; 0.980785;,
+      -0.108386;-0.162212; 0.980785;,
+      -0.137950;-0.137950; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.074658;-0.180240; 0.980785;,
+      -0.108386;-0.162212; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+      -0.074658;-0.180240; 0.980785;,
+      -0.146447;-0.353553; 0.923880;,
+      -0.212607;-0.318190; 0.923880;,
+      -0.108386;-0.162212; 0.980785;,
+      -0.146447;-0.353553; 0.923880;,
+      -0.212607;-0.513280; 0.831470;,
+      -0.308658;-0.461940; 0.831470;,
+      -0.212607;-0.318190; 0.923880;,
+      -0.212607;-0.513280; 0.831470;,
+      -0.270598;-0.653281; 0.707107;,
+      -0.392847;-0.587938; 0.707107;,
+      -0.308658;-0.461940; 0.831470;,
+      -0.270598;-0.653281; 0.707107;,
+      -0.318189;-0.768177; 0.555570;,
+      -0.461939;-0.691341; 0.555570;,
+      -0.392847;-0.587938; 0.707107;,
+      -0.318189;-0.768177; 0.555570;,
+      -0.353553;-0.853553; 0.382683;,
+      -0.513280;-0.768177; 0.382683;,
+      -0.461939;-0.691341; 0.555570;,
+      -0.353553;-0.853553; 0.382683;,
+      -0.375330;-0.906127; 0.195090;,
+      -0.544895;-0.815493; 0.195090;,
+      -0.513280;-0.768177; 0.382683;,
+      -0.375330;-0.906127; 0.195090;,
+      -0.382683;-0.923879; 0.000000;,
+      -0.555569;-0.831469; 0.000000;,
+      -0.544895;-0.815493; 0.195090;,
+      -0.382683;-0.923879; 0.000000;,
+      -0.375330;-0.906127;-0.195090;,
+      -0.544895;-0.815493;-0.195090;,
+      -0.555569;-0.831469; 0.000000;,
+      -0.375330;-0.906127;-0.195090;,
+      -0.353553;-0.853553;-0.382683;,
+      -0.513280;-0.768178;-0.382683;,
+      -0.544895;-0.815493;-0.195090;,
+      -0.353553;-0.853553;-0.382683;,
+      -0.318189;-0.768177;-0.555570;,
+      -0.461939;-0.691341;-0.555570;,
+      -0.513280;-0.768178;-0.382683;,
+      -0.318189;-0.768177;-0.555570;,
+      -0.270598;-0.653281;-0.707107;,
+      -0.392847;-0.587938;-0.707107;,
+      -0.461939;-0.691341;-0.555570;,
+      -0.270598;-0.653281;-0.707107;,
+      -0.212607;-0.513280;-0.831470;,
+      -0.308658;-0.461940;-0.831470;,
+      -0.392847;-0.587938;-0.707107;,
+      -0.212607;-0.513280;-0.831470;,
+      -0.146446;-0.353553;-0.923880;,
+      -0.212607;-0.318189;-0.923880;,
+      -0.308658;-0.461940;-0.831470;,
+      -0.146446;-0.353553;-0.923880;,
+      -0.074658;-0.180240;-0.980785;,
+      -0.108386;-0.162211;-0.980785;,
+      -0.212607;-0.318189;-0.923880;,
+      -0.074658;-0.180240;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.108386;-0.162211;-0.980785;,
+      -0.038060;-0.191341;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.074658;-0.180240;-0.980785;,
+      -0.074658;-0.375330;-0.923880;,
+      -0.038060;-0.191341;-0.980785;,
+      -0.074658;-0.180240;-0.980785;,
+      -0.146446;-0.353553;-0.923880;,
+      -0.108386;-0.544895;-0.831470;,
+      -0.074658;-0.375330;-0.923880;,
+      -0.146446;-0.353553;-0.923880;,
+      -0.212607;-0.513280;-0.831470;,
+      -0.137950;-0.693520;-0.707107;,
+      -0.108386;-0.544895;-0.831470;,
+      -0.212607;-0.513280;-0.831470;,
+      -0.270598;-0.653281;-0.707107;,
+      -0.162211;-0.815493;-0.555570;,
+      -0.137950;-0.693520;-0.707107;,
+      -0.270598;-0.653281;-0.707107;,
+      -0.318189;-0.768177;-0.555570;,
+      -0.180240;-0.906127;-0.382683;,
+      -0.162211;-0.815493;-0.555570;,
+      -0.318189;-0.768177;-0.555570;,
+      -0.353553;-0.853553;-0.382683;,
+      -0.191341;-0.961939;-0.195090;,
+      -0.180240;-0.906127;-0.382683;,
+      -0.353553;-0.853553;-0.382683;,
+      -0.375330;-0.906127;-0.195090;,
+      -0.195090;-0.980784; 0.000000;,
+      -0.191341;-0.961939;-0.195090;,
+      -0.375330;-0.906127;-0.195090;,
+      -0.382683;-0.923879; 0.000000;,
+      -0.191341;-0.961939; 0.195090;,
+      -0.195090;-0.980784; 0.000000;,
+      -0.382683;-0.923879; 0.000000;,
+      -0.375330;-0.906127; 0.195090;,
+      -0.180240;-0.906127; 0.382683;,
+      -0.191341;-0.961939; 0.195090;,
+      -0.375330;-0.906127; 0.195090;,
+      -0.353553;-0.853553; 0.382683;,
+      -0.162211;-0.815493; 0.555570;,
+      -0.180240;-0.906127; 0.382683;,
+      -0.353553;-0.853553; 0.382683;,
+      -0.318189;-0.768177; 0.555570;,
+      -0.137950;-0.693520; 0.707107;,
+      -0.162211;-0.815493; 0.555570;,
+      -0.318189;-0.768177; 0.555570;,
+      -0.270598;-0.653281; 0.707107;,
+      -0.108386;-0.544895; 0.831470;,
+      -0.137950;-0.693520; 0.707107;,
+      -0.270598;-0.653281; 0.707107;,
+      -0.212607;-0.513280; 0.831470;,
+      -0.074658;-0.375330; 0.923880;,
+      -0.108386;-0.544895; 0.831470;,
+      -0.212607;-0.513280; 0.831470;,
+      -0.146447;-0.353553; 0.923880;,
+      -0.038060;-0.191342; 0.980785;,
+      -0.074658;-0.375330; 0.923880;,
+      -0.146447;-0.353553; 0.923880;,
+      -0.074658;-0.180240; 0.980785;,
+      -0.038060;-0.191342; 0.980785;,
+      -0.074658;-0.180240; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.000000;-0.195090; 0.980785;,
+      -0.038060;-0.191342; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.000000;-0.195090; 0.980785;,
+       0.000000;-0.382683; 0.923880;,
+      -0.074658;-0.375330; 0.923880;,
+      -0.038060;-0.191342; 0.980785;,
+       0.000000;-0.382683; 0.923880;,
+       0.000000;-0.555570; 0.831470;,
+      -0.108386;-0.544895; 0.831470;,
+      -0.074658;-0.375330; 0.923880;,
+       0.000000;-0.555570; 0.831470;,
+       0.000000;-0.707107; 0.707107;,
+      -0.137950;-0.693520; 0.707107;,
+      -0.108386;-0.544895; 0.831470;,
+       0.000000;-0.707107; 0.707107;,
+       0.000000;-0.831469; 0.555570;,
+      -0.162211;-0.815493; 0.555570;,
+      -0.137950;-0.693520; 0.707107;,
+       0.000000;-0.831469; 0.555570;,
+       0.000000;-0.923879; 0.382683;,
+      -0.180240;-0.906127; 0.382683;,
+      -0.162211;-0.815493; 0.555570;,
+       0.000000;-0.923879; 0.382683;,
+       0.000000;-0.980785; 0.195090;,
+      -0.191341;-0.961939; 0.195090;,
+      -0.180240;-0.906127; 0.382683;,
+       0.000000;-0.980785; 0.195090;,
+       0.000000;-0.999999; 0.000000;,
+      -0.195090;-0.980784; 0.000000;,
+      -0.191341;-0.961939; 0.195090;,
+       0.000000;-0.999999; 0.000000;,
+       0.000000;-0.980785;-0.195090;,
+      -0.191341;-0.961939;-0.195090;,
+      -0.195090;-0.980784; 0.000000;,
+       0.000000;-0.980785;-0.195090;,
+       0.000000;-0.923879;-0.382683;,
+      -0.180240;-0.906127;-0.382683;,
+      -0.191341;-0.961939;-0.195090;,
+       0.000000;-0.923879;-0.382683;,
+       0.000000;-0.831469;-0.555570;,
+      -0.162211;-0.815493;-0.555570;,
+      -0.180240;-0.906127;-0.382683;,
+       0.000000;-0.831469;-0.555570;,
+       0.000000;-0.707107;-0.707107;,
+      -0.137950;-0.693520;-0.707107;,
+      -0.162211;-0.815493;-0.555570;,
+       0.000000;-0.707107;-0.707107;,
+       0.000000;-0.555570;-0.831470;,
+      -0.108386;-0.544895;-0.831470;,
+      -0.137950;-0.693520;-0.707107;,
+       0.000000;-0.555570;-0.831470;,
+       0.000000;-0.382683;-0.923880;,
+      -0.074658;-0.375330;-0.923880;,
+      -0.108386;-0.544895;-0.831470;,
+       0.000000;-0.382683;-0.923880;,
+       0.000000;-0.195090;-0.980785;,
+      -0.038060;-0.191341;-0.980785;,
+      -0.074658;-0.375330;-0.923880;,
+       0.000000;-0.195090;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+      -0.038060;-0.191341;-0.980785;,
+       0.038060;-0.191341;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.000000;-0.195090;-0.980785;,
+       0.074658;-0.375330;-0.923880;,
+       0.038060;-0.191341;-0.980785;,
+       0.000000;-0.195090;-0.980785;,
+       0.000000;-0.382683;-0.923880;,
+       0.108386;-0.544895;-0.831470;,
+       0.074658;-0.375330;-0.923880;,
+       0.000000;-0.382683;-0.923880;,
+       0.000000;-0.555570;-0.831470;,
+       0.137950;-0.693520;-0.707107;,
+       0.108386;-0.544895;-0.831470;,
+       0.000000;-0.555570;-0.831470;,
+       0.000000;-0.707107;-0.707107;,
+       0.162212;-0.815493;-0.555570;,
+       0.137950;-0.693520;-0.707107;,
+       0.000000;-0.707107;-0.707107;,
+       0.000000;-0.831469;-0.555570;,
+       0.180240;-0.906127;-0.382683;,
+       0.162212;-0.815493;-0.555570;,
+       0.000000;-0.831469;-0.555570;,
+       0.000000;-0.923879;-0.382683;,
+       0.191342;-0.961939;-0.195090;,
+       0.180240;-0.906127;-0.382683;,
+       0.000000;-0.923879;-0.382683;,
+       0.000000;-0.980785;-0.195090;,
+       0.195091;-0.980784; 0.000000;,
+       0.191342;-0.961939;-0.195090;,
+       0.000000;-0.980785;-0.195090;,
+       0.000000;-0.999999; 0.000000;,
+       0.191342;-0.961939; 0.195090;,
+       0.195091;-0.980784; 0.000000;,
+       0.000000;-0.999999; 0.000000;,
+       0.000000;-0.980785; 0.195090;,
+       0.180240;-0.906127; 0.382683;,
+       0.191342;-0.961939; 0.195090;,
+       0.000000;-0.980785; 0.195090;,
+       0.000000;-0.923879; 0.382683;,
+       0.162212;-0.815493; 0.555570;,
+       0.180240;-0.906127; 0.382683;,
+       0.000000;-0.923879; 0.382683;,
+       0.000000;-0.831469; 0.555570;,
+       0.137950;-0.693520; 0.707107;,
+       0.162212;-0.815493; 0.555570;,
+       0.000000;-0.831469; 0.555570;,
+       0.000000;-0.707107; 0.707107;,
+       0.108386;-0.544895; 0.831470;,
+       0.137950;-0.693520; 0.707107;,
+       0.000000;-0.707107; 0.707107;,
+       0.000000;-0.555570; 0.831470;,
+       0.074658;-0.375330; 0.923880;,
+       0.108386;-0.544895; 0.831470;,
+       0.000000;-0.555570; 0.831470;,
+       0.000000;-0.382683; 0.923880;,
+       0.038060;-0.191342; 0.980785;,
+       0.074658;-0.375330; 0.923880;,
+       0.000000;-0.382683; 0.923880;,
+       0.000000;-0.195090; 0.980785;,
+       0.038060;-0.191342; 0.980785;,
+       0.000000;-0.195090; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.074658;-0.180240; 0.980785;,
+       0.038060;-0.191342; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.074658;-0.180240; 0.980785;,
+       0.146447;-0.353553; 0.923880;,
+       0.074658;-0.375330; 0.923880;,
+       0.038060;-0.191342; 0.980785;,
+       0.146447;-0.353553; 0.923880;,
+       0.212607;-0.513279; 0.831470;,
+       0.108386;-0.544895; 0.831470;,
+       0.074658;-0.375330; 0.923880;,
+       0.212607;-0.513279; 0.831470;,
+       0.270598;-0.653281; 0.707107;,
+       0.137950;-0.693520; 0.707107;,
+       0.108386;-0.544895; 0.831470;,
+       0.270598;-0.653281; 0.707107;,
+       0.318190;-0.768177; 0.555570;,
+       0.162212;-0.815493; 0.555570;,
+       0.137950;-0.693520; 0.707107;,
+       0.318190;-0.768177; 0.555570;,
+       0.353553;-0.853553; 0.382683;,
+       0.180240;-0.906127; 0.382683;,
+       0.162212;-0.815493; 0.555570;,
+       0.353553;-0.853553; 0.382683;,
+       0.375330;-0.906127; 0.195090;,
+       0.191342;-0.961939; 0.195090;,
+       0.180240;-0.906127; 0.382683;,
+       0.375330;-0.906127; 0.195090;,
+       0.382683;-0.923878; 0.000000;,
+       0.195091;-0.980784; 0.000000;,
+       0.191342;-0.961939; 0.195090;,
+       0.382683;-0.923878; 0.000000;,
+       0.375330;-0.906127;-0.195090;,
+       0.191342;-0.961939;-0.195090;,
+       0.195091;-0.980784; 0.000000;,
+       0.375330;-0.906127;-0.195090;,
+       0.353553;-0.853553;-0.382683;,
+       0.180240;-0.906127;-0.382683;,
+       0.191342;-0.961939;-0.195090;,
+       0.353553;-0.853553;-0.382683;,
+       0.318190;-0.768177;-0.555570;,
+       0.162212;-0.815493;-0.555570;,
+       0.180240;-0.906127;-0.382683;,
+       0.318190;-0.768177;-0.555570;,
+       0.270598;-0.653281;-0.707107;,
+       0.137950;-0.693520;-0.707107;,
+       0.162212;-0.815493;-0.555570;,
+       0.270598;-0.653281;-0.707107;,
+       0.212607;-0.513280;-0.831470;,
+       0.108386;-0.544895;-0.831470;,
+       0.137950;-0.693520;-0.707107;,
+       0.212607;-0.513280;-0.831470;,
+       0.146447;-0.353553;-0.923880;,
+       0.074658;-0.375330;-0.923880;,
+       0.108386;-0.544895;-0.831470;,
+       0.146447;-0.353553;-0.923880;,
+       0.074658;-0.180240;-0.980785;,
+       0.038060;-0.191341;-0.980785;,
+       0.074658;-0.375330;-0.923880;,
+       0.074658;-0.180240;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.038060;-0.191341;-0.980785;,
+       0.108386;-0.162211;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.074658;-0.180240;-0.980785;,
+       0.212607;-0.318189;-0.923880;,
+       0.108386;-0.162211;-0.980785;,
+       0.074658;-0.180240;-0.980785;,
+       0.146447;-0.353553;-0.923880;,
+       0.308658;-0.461939;-0.831470;,
+       0.212607;-0.318189;-0.923880;,
+       0.146447;-0.353553;-0.923880;,
+       0.212607;-0.513280;-0.831470;,
+       0.392847;-0.587938;-0.707107;,
+       0.308658;-0.461939;-0.831470;,
+       0.212607;-0.513280;-0.831470;,
+       0.270598;-0.653281;-0.707107;,
+       0.461940;-0.691341;-0.555570;,
+       0.392847;-0.587938;-0.707107;,
+       0.270598;-0.653281;-0.707107;,
+       0.318190;-0.768177;-0.555570;,
+       0.513280;-0.768177;-0.382683;,
+       0.461940;-0.691341;-0.555570;,
+       0.318190;-0.768177;-0.555570;,
+       0.353553;-0.853553;-0.382683;,
+       0.544895;-0.815493;-0.195090;,
+       0.513280;-0.768177;-0.382683;,
+       0.353553;-0.853553;-0.382683;,
+       0.375330;-0.906127;-0.195090;,
+       0.555570;-0.831468; 0.000000;,
+       0.544895;-0.815493;-0.195090;,
+       0.375330;-0.906127;-0.195090;,
+       0.382683;-0.923878; 0.000000;,
+       0.544895;-0.815493; 0.195090;,
+       0.555570;-0.831468; 0.000000;,
+       0.382683;-0.923878; 0.000000;,
+       0.375330;-0.906127; 0.195090;,
+       0.513280;-0.768177; 0.382683;,
+       0.544895;-0.815493; 0.195090;,
+       0.375330;-0.906127; 0.195090;,
+       0.353553;-0.853553; 0.382683;,
+       0.461940;-0.691341; 0.555570;,
+       0.513280;-0.768177; 0.382683;,
+       0.353553;-0.853553; 0.382683;,
+       0.318190;-0.768177; 0.555570;,
+       0.392847;-0.587938; 0.707107;,
+       0.461940;-0.691341; 0.555570;,
+       0.318190;-0.768177; 0.555570;,
+       0.270598;-0.653281; 0.707107;,
+       0.308658;-0.461939; 0.831470;,
+       0.392847;-0.587938; 0.707107;,
+       0.270598;-0.653281; 0.707107;,
+       0.212607;-0.513279; 0.831470;,
+       0.212607;-0.318189; 0.923880;,
+       0.308658;-0.461939; 0.831470;,
+       0.212607;-0.513279; 0.831470;,
+       0.146447;-0.353553; 0.923880;,
+       0.108386;-0.162212; 0.980785;,
+       0.212607;-0.318189; 0.923880;,
+       0.146447;-0.353553; 0.923880;,
+       0.074658;-0.180240; 0.980785;,
+       0.108386;-0.162212; 0.980785;,
+       0.074658;-0.180240; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.137950;-0.137950; 0.980785;,
+       0.108386;-0.162212; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.137950;-0.137950; 0.980785;,
+       0.270598;-0.270598; 0.923880;,
+       0.212607;-0.318189; 0.923880;,
+       0.108386;-0.162212; 0.980785;,
+       0.270598;-0.270598; 0.923880;,
+       0.392847;-0.392847; 0.831470;,
+       0.308658;-0.461939; 0.831470;,
+       0.212607;-0.318189; 0.923880;,
+       0.392847;-0.392847; 0.831470;,
+       0.500000;-0.500000; 0.707107;,
+       0.392847;-0.587938; 0.707107;,
+       0.308658;-0.461939; 0.831470;,
+       0.500000;-0.500000; 0.707107;,
+       0.587938;-0.587937; 0.555570;,
+       0.461940;-0.691341; 0.555570;,
+       0.392847;-0.587938; 0.707107;,
+       0.587938;-0.587937; 0.555570;,
+       0.653281;-0.653281; 0.382683;,
+       0.513280;-0.768177; 0.382683;,
+       0.461940;-0.691341; 0.555570;,
+       0.653281;-0.653281; 0.382683;,
+       0.693520;-0.693519; 0.195090;,
+       0.544895;-0.815493; 0.195090;,
+       0.513280;-0.768177; 0.382683;,
+       0.693520;-0.693519; 0.195090;,
+       0.707106;-0.707106; 0.000000;,
+       0.555570;-0.831468; 0.000000;,
+       0.544895;-0.815493; 0.195090;,
+       0.707106;-0.707106; 0.000000;,
+       0.693520;-0.693519;-0.195090;,
+       0.544895;-0.815493;-0.195090;,
+       0.555570;-0.831468; 0.000000;,
+       0.693520;-0.693519;-0.195090;,
+       0.653281;-0.653281;-0.382683;,
+       0.513280;-0.768177;-0.382683;,
+       0.544895;-0.815493;-0.195090;,
+       0.653281;-0.653281;-0.382683;,
+       0.587938;-0.587937;-0.555570;,
+       0.461940;-0.691341;-0.555570;,
+       0.513280;-0.768177;-0.382683;,
+       0.587938;-0.587937;-0.555570;,
+       0.500000;-0.500000;-0.707107;,
+       0.392847;-0.587938;-0.707107;,
+       0.461940;-0.691341;-0.555570;,
+       0.500000;-0.500000;-0.707107;,
+       0.392847;-0.392847;-0.831470;,
+       0.308658;-0.461939;-0.831470;,
+       0.392847;-0.587938;-0.707107;,
+       0.392847;-0.392847;-0.831470;,
+       0.270598;-0.270598;-0.923880;,
+       0.212607;-0.318189;-0.923880;,
+       0.308658;-0.461939;-0.831470;,
+       0.270598;-0.270598;-0.923880;,
+       0.137949;-0.137949;-0.980785;,
+       0.108386;-0.162211;-0.980785;,
+       0.212607;-0.318189;-0.923880;,
+       0.137949;-0.137949;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.108386;-0.162211;-0.980785;,
+       0.162211;-0.108386;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.137949;-0.137949;-0.980785;,
+       0.318189;-0.212607;-0.923880;,
+       0.162211;-0.108386;-0.980785;,
+       0.137949;-0.137949;-0.980785;,
+       0.270598;-0.270598;-0.923880;,
+       0.461939;-0.308658;-0.831470;,
+       0.318189;-0.212607;-0.923880;,
+       0.270598;-0.270598;-0.923880;,
+       0.392847;-0.392847;-0.831470;,
+       0.587938;-0.392847;-0.707107;,
+       0.461939;-0.308658;-0.831470;,
+       0.392847;-0.392847;-0.831470;,
+       0.500000;-0.500000;-0.707107;,
+       0.691341;-0.461939;-0.555570;,
+       0.587938;-0.392847;-0.707107;,
+       0.500000;-0.500000;-0.707107;,
+       0.587938;-0.587937;-0.555570;,
+       0.768178;-0.513280;-0.382683;,
+       0.691341;-0.461939;-0.555570;,
+       0.587938;-0.587937;-0.555570;,
+       0.653281;-0.653281;-0.382683;,
+       0.815493;-0.544895;-0.195090;,
+       0.768178;-0.513280;-0.382683;,
+       0.653281;-0.653281;-0.382683;,
+       0.693520;-0.693519;-0.195090;,
+       0.831469;-0.555569; 0.000000;,
+       0.815493;-0.544895;-0.195090;,
+       0.693520;-0.693519;-0.195090;,
+       0.707106;-0.707106; 0.000000;,
+       0.815493;-0.544895; 0.195090;,
+       0.831469;-0.555569; 0.000000;,
+       0.707106;-0.707106; 0.000000;,
+       0.693520;-0.693519; 0.195090;,
+       0.768177;-0.513280; 0.382683;,
+       0.815493;-0.544895; 0.195090;,
+       0.693520;-0.693519; 0.195090;,
+       0.653281;-0.653281; 0.382683;,
+       0.691341;-0.461939; 0.555570;,
+       0.768177;-0.513280; 0.382683;,
+       0.653281;-0.653281; 0.382683;,
+       0.587938;-0.587937; 0.555570;,
+       0.587938;-0.392847; 0.707107;,
+       0.691341;-0.461939; 0.555570;,
+       0.587938;-0.587937; 0.555570;,
+       0.500000;-0.500000; 0.707107;,
+       0.461939;-0.308658; 0.831470;,
+       0.587938;-0.392847; 0.707107;,
+       0.500000;-0.500000; 0.707107;,
+       0.392847;-0.392847; 0.831470;,
+       0.318190;-0.212607; 0.923880;,
+       0.461939;-0.308658; 0.831470;,
+       0.392847;-0.392847; 0.831470;,
+       0.270598;-0.270598; 0.923880;,
+       0.162212;-0.108386; 0.980785;,
+       0.318190;-0.212607; 0.923880;,
+       0.270598;-0.270598; 0.923880;,
+       0.137950;-0.137950; 0.980785;,
+       0.162212;-0.108386; 0.980785;,
+       0.137950;-0.137950; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.180240;-0.074658; 0.980785;,
+       0.162212;-0.108386; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.180240;-0.074658; 0.980785;,
+       0.353553;-0.146446; 0.923880;,
+       0.318190;-0.212607; 0.923880;,
+       0.162212;-0.108386; 0.980785;,
+       0.353553;-0.146446; 0.923880;,
+       0.513279;-0.212607; 0.831470;,
+       0.461939;-0.308658; 0.831470;,
+       0.318190;-0.212607; 0.923880;,
+       0.513279;-0.212607; 0.831470;,
+       0.653281;-0.270598; 0.707107;,
+       0.587938;-0.392847; 0.707107;,
+       0.461939;-0.308658; 0.831470;,
+       0.653281;-0.270598; 0.707107;,
+       0.768177;-0.318189; 0.555570;,
+       0.691341;-0.461939; 0.555570;,
+       0.587938;-0.392847; 0.707107;,
+       0.768177;-0.318189; 0.555570;,
+       0.853553;-0.353553; 0.382683;,
+       0.768177;-0.513280; 0.382683;,
+       0.691341;-0.461939; 0.555570;,
+       0.853553;-0.353553; 0.382683;,
+       0.906127;-0.375330; 0.195090;,
+       0.815493;-0.544895; 0.195090;,
+       0.768177;-0.513280; 0.382683;,
+       0.906127;-0.375330; 0.195090;,
+       0.923879;-0.382683; 0.000000;,
+       0.831469;-0.555569; 0.000000;,
+       0.815493;-0.544895; 0.195090;,
+       0.923879;-0.382683; 0.000000;,
+       0.906127;-0.375330;-0.195090;,
+       0.815493;-0.544895;-0.195090;,
+       0.831469;-0.555569; 0.000000;,
+       0.906127;-0.375330;-0.195090;,
+       0.853553;-0.353553;-0.382683;,
+       0.768178;-0.513280;-0.382683;,
+       0.815493;-0.544895;-0.195090;,
+       0.853553;-0.353553;-0.382683;,
+       0.768177;-0.318189;-0.555570;,
+       0.691341;-0.461939;-0.555570;,
+       0.768178;-0.513280;-0.382683;,
+       0.768177;-0.318189;-0.555570;,
+       0.653281;-0.270598;-0.707107;,
+       0.587938;-0.392847;-0.707107;,
+       0.691341;-0.461939;-0.555570;,
+       0.653281;-0.270598;-0.707107;,
+       0.513280;-0.212607;-0.831470;,
+       0.461939;-0.308658;-0.831470;,
+       0.587938;-0.392847;-0.707107;,
+       0.513280;-0.212607;-0.831470;,
+       0.353553;-0.146446;-0.923880;,
+       0.318189;-0.212607;-0.923880;,
+       0.461939;-0.308658;-0.831470;,
+       0.353553;-0.146446;-0.923880;,
+       0.180240;-0.074658;-0.980785;,
+       0.162211;-0.108386;-0.980785;,
+       0.318189;-0.212607;-0.923880;,
+       0.180240;-0.074658;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.162211;-0.108386;-0.980785;,
+       0.191341;-0.038060;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.180240;-0.074658;-0.980785;,
+       0.375330;-0.074658;-0.923880;,
+       0.191341;-0.038060;-0.980785;,
+       0.180240;-0.074658;-0.980785;,
+       0.353553;-0.146446;-0.923880;,
+       0.544895;-0.108386;-0.831470;,
+       0.375330;-0.074658;-0.923880;,
+       0.353553;-0.146446;-0.923880;,
+       0.513280;-0.212607;-0.831470;,
+       0.693520;-0.137950;-0.707107;,
+       0.544895;-0.108386;-0.831470;,
+       0.513280;-0.212607;-0.831470;,
+       0.653281;-0.270598;-0.707107;,
+       0.815493;-0.162211;-0.555570;,
+       0.693520;-0.137950;-0.707107;,
+       0.653281;-0.270598;-0.707107;,
+       0.768177;-0.318189;-0.555570;,
+       0.906127;-0.180240;-0.382683;,
+       0.815493;-0.162211;-0.555570;,
+       0.768177;-0.318189;-0.555570;,
+       0.853553;-0.353553;-0.382683;,
+       0.961939;-0.191341;-0.195090;,
+       0.906127;-0.180240;-0.382683;,
+       0.853553;-0.353553;-0.382683;,
+       0.906127;-0.375330;-0.195090;,
+       0.980784;-0.195090; 0.000000;,
+       0.961939;-0.191341;-0.195090;,
+       0.906127;-0.375330;-0.195090;,
+       0.923879;-0.382683; 0.000000;,
+       0.961939;-0.191341; 0.195090;,
+       0.980784;-0.195090; 0.000000;,
+       0.923879;-0.382683; 0.000000;,
+       0.906127;-0.375330; 0.195090;,
+       0.906127;-0.180240; 0.382683;,
+       0.961939;-0.191341; 0.195090;,
+       0.906127;-0.375330; 0.195090;,
+       0.853553;-0.353553; 0.382683;,
+       0.815493;-0.162211; 0.555570;,
+       0.906127;-0.180240; 0.382683;,
+       0.853553;-0.353553; 0.382683;,
+       0.768177;-0.318189; 0.555570;,
+       0.693520;-0.137950; 0.707107;,
+       0.815493;-0.162211; 0.555570;,
+       0.768177;-0.318189; 0.555570;,
+       0.653281;-0.270598; 0.707107;,
+       0.544895;-0.108386; 0.831470;,
+       0.693520;-0.137950; 0.707107;,
+       0.653281;-0.270598; 0.707107;,
+       0.513279;-0.212607; 0.831470;,
+       0.375330;-0.074658; 0.923880;,
+       0.544895;-0.108386; 0.831470;,
+       0.513279;-0.212607; 0.831470;,
+       0.353553;-0.146446; 0.923880;,
+       0.191342;-0.038060; 0.980785;,
+       0.375330;-0.074658; 0.923880;,
+       0.353553;-0.146446; 0.923880;,
+       0.180240;-0.074658; 0.980785;,
+       0.191342;-0.038060; 0.980785;,
+       0.180240;-0.074658; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.195090; 0.000000; 0.980785;,
+       0.191342;-0.038060; 0.980785;,
+       0.000000; 0.000000; 1.000000;,
+       0.195090; 0.000000; 0.980785;,
+       0.382683; 0.000000; 0.923880;,
+       0.375330;-0.074658; 0.923880;,
+       0.191342;-0.038060; 0.980785;,
+       0.382683; 0.000000; 0.923880;,
+       0.555570; 0.000000; 0.831470;,
+       0.544895;-0.108386; 0.831470;,
+       0.375330;-0.074658; 0.923880;,
+       0.555570; 0.000000; 0.831470;,
+       0.707107; 0.000000; 0.707107;,
+       0.693520;-0.137950; 0.707107;,
+       0.544895;-0.108386; 0.831470;,
+       0.707107; 0.000000; 0.707107;,
+       0.831469; 0.000000; 0.555570;,
+       0.815493;-0.162211; 0.555570;,
+       0.693520;-0.137950; 0.707107;,
+       0.831469; 0.000000; 0.555570;,
+       0.923879; 0.000000; 0.382683;,
+       0.906127;-0.180240; 0.382683;,
+       0.815493;-0.162211; 0.555570;,
+       0.923879; 0.000000; 0.382683;,
+       0.980785; 0.000000; 0.195090;,
+       0.961939;-0.191341; 0.195090;,
+       0.906127;-0.180240; 0.382683;,
+       0.980785; 0.000000; 0.195090;,
+       0.999999; 0.000000; 0.000000;,
+       0.980784;-0.195090; 0.000000;,
+       0.961939;-0.191341; 0.195090;,
+       0.999999; 0.000000; 0.000000;,
+       0.980785; 0.000000;-0.195090;,
+       0.961939;-0.191341;-0.195090;,
+       0.980784;-0.195090; 0.000000;,
+       0.980785; 0.000000;-0.195090;,
+       0.923879; 0.000000;-0.382683;,
+       0.906127;-0.180240;-0.382683;,
+       0.961939;-0.191341;-0.195090;,
+       0.923879; 0.000000;-0.382683;,
+       0.831469; 0.000000;-0.555570;,
+       0.815493;-0.162211;-0.555570;,
+       0.906127;-0.180240;-0.382683;,
+       0.831469; 0.000000;-0.555570;,
+       0.707107; 0.000000;-0.707107;,
+       0.693520;-0.137950;-0.707107;,
+       0.815493;-0.162211;-0.555570;,
+       0.707107; 0.000000;-0.707107;,
+       0.555570; 0.000000;-0.831470;,
+       0.544895;-0.108386;-0.831470;,
+       0.693520;-0.137950;-0.707107;,
+       0.555570; 0.000000;-0.831470;,
+       0.382683; 0.000000;-0.923880;,
+       0.375330;-0.074658;-0.923880;,
+       0.544895;-0.108386;-0.831470;,
+       0.382683; 0.000000;-0.923880;,
+       0.195090; 0.000000;-0.980785;,
+       0.191341;-0.038060;-0.980785;,
+       0.375330;-0.074658;-0.923880;,
+       0.195090; 0.000000;-0.980785;,
+      -0.000000;-0.000000;-1.000000;,
+       0.191341;-0.038060;-0.980785;;
+      512;
+      3;0;1;2;,
+      4;3;4;5;6;,
+      4;7;8;9;10;,
+      4;11;12;13;14;,
+      4;15;16;17;18;,
+      4;19;20;21;22;,
+      4;23;24;25;26;,
+      4;27;28;29;30;,
+      4;31;32;33;34;,
+      4;35;36;37;38;,
+      4;39;40;41;42;,
+      4;43;44;45;46;,
+      4;47;48;49;50;,
+      4;51;52;53;54;,
+      4;55;56;57;58;,
+      3;59;60;61;,
+      3;62;63;64;,
+      4;65;66;67;68;,
+      4;69;70;71;72;,
+      4;73;74;75;76;,
+      4;77;78;79;80;,
+      4;81;82;83;84;,
+      4;85;86;87;88;,
+      4;89;90;91;92;,
+      4;93;94;95;96;,
+      4;97;98;99;100;,
+      4;101;102;103;104;,
+      4;105;106;107;108;,
+      4;109;110;111;112;,
+      4;113;114;115;116;,
+      4;117;118;119;120;,
+      3;121;122;123;,
+      3;124;125;126;,
+      4;127;128;129;130;,
+      4;131;132;133;134;,
+      4;135;136;137;138;,
+      4;139;140;141;142;,
+      4;143;144;145;146;,
+      4;147;148;149;150;,
+      4;151;152;153;154;,
+      4;155;156;157;158;,
+      4;159;160;161;162;,
+      4;163;164;165;166;,
+      4;167;168;169;170;,
+      4;171;172;173;174;,
+      4;175;176;177;178;,
+      4;179;180;181;182;,
+      3;183;184;185;,
+      3;186;187;188;,
+      4;189;190;191;192;,
+      4;193;194;195;196;,
+      4;197;198;199;200;,
+      4;201;202;203;204;,
+      4;205;206;207;208;,
+      4;209;210;211;212;,
+      4;213;214;215;216;,
+      4;217;218;219;220;,
+      4;221;222;223;224;,
+      4;225;226;227;228;,
+      4;229;230;231;232;,
+      4;233;234;235;236;,
+      4;237;238;239;240;,
+      4;241;242;243;244;,
+      3;245;246;247;,
+      3;248;249;250;,
+      4;251;252;253;254;,
+      4;255;256;257;258;,
+      4;259;260;261;262;,
+      4;263;264;265;266;,
+      4;267;268;269;270;,
+      4;271;272;273;274;,
+      4;275;276;277;278;,
+      4;279;280;281;282;,
+      4;283;284;285;286;,
+      4;287;288;289;290;,
+      4;291;292;293;294;,
+      4;295;296;297;298;,
+      4;299;300;301;302;,
+      4;303;304;305;306;,
+      3;307;308;309;,
+      3;310;311;312;,
+      4;313;314;315;316;,
+      4;317;318;319;320;,
+      4;321;322;323;324;,
+      4;325;326;327;328;,
+      4;329;330;331;332;,
+      4;333;334;335;336;,
+      4;337;338;339;340;,
+      4;341;342;343;344;,
+      4;345;346;347;348;,
+      4;349;350;351;352;,
+      4;353;354;355;356;,
+      4;357;358;359;360;,
+      4;361;362;363;364;,
+      4;365;366;367;368;,
+      3;369;370;371;,
+      3;372;373;374;,
+      4;375;376;377;378;,
+      4;379;380;381;382;,
+      4;383;384;385;386;,
+      4;387;388;389;390;,
+      4;391;392;393;394;,
+      4;395;396;397;398;,
+      4;399;400;401;402;,
+      4;403;404;405;406;,
+      4;407;408;409;410;,
+      4;411;412;413;414;,
+      4;415;416;417;418;,
+      4;419;420;421;422;,
+      4;423;424;425;426;,
+      4;427;428;429;430;,
+      3;431;432;433;,
+      3;434;435;436;,
+      4;437;438;439;440;,
+      4;441;442;443;444;,
+      4;445;446;447;448;,
+      4;449;450;451;452;,
+      4;453;454;455;456;,
+      4;457;458;459;460;,
+      4;461;462;463;464;,
+      4;465;466;467;468;,
+      4;469;470;471;472;,
+      4;473;474;475;476;,
+      4;477;478;479;480;,
+      4;481;482;483;484;,
+      4;485;486;487;488;,
+      4;489;490;491;492;,
+      3;493;494;495;,
+      3;496;497;498;,
+      4;499;500;501;502;,
+      4;503;504;505;506;,
+      4;507;508;509;510;,
+      4;511;512;513;514;,
+      4;515;516;517;518;,
+      4;519;520;521;522;,
+      4;523;524;525;526;,
+      4;527;528;529;530;,
+      4;531;532;533;534;,
+      4;535;536;537;538;,
+      4;539;540;541;542;,
+      4;543;544;545;546;,
+      4;547;548;549;550;,
+      4;551;552;553;554;,
+      3;555;556;557;,
+      3;558;559;560;,
+      4;561;562;563;564;,
+      4;565;566;567;568;,
+      4;569;570;571;572;,
+      4;573;574;575;576;,
+      4;577;578;579;580;,
+      4;581;582;583;584;,
+      4;585;586;587;588;,
+      4;589;590;591;592;,
+      4;593;594;595;596;,
+      4;597;598;599;600;,
+      4;601;602;603;604;,
+      4;605;606;607;608;,
+      4;609;610;611;612;,
+      4;613;614;615;616;,
+      3;617;618;619;,
+      3;620;621;622;,
+      4;623;624;625;626;,
+      4;627;628;629;630;,
+      4;631;632;633;634;,
+      4;635;636;637;638;,
+      4;639;640;641;642;,
+      4;643;644;645;646;,
+      4;647;648;649;650;,
+      4;651;652;653;654;,
+      4;655;656;657;658;,
+      4;659;660;661;662;,
+      4;663;664;665;666;,
+      4;667;668;669;670;,
+      4;671;672;673;674;,
+      4;675;676;677;678;,
+      3;679;680;681;,
+      3;682;683;684;,
+      4;685;686;687;688;,
+      4;689;690;691;692;,
+      4;693;694;695;696;,
+      4;697;698;699;700;,
+      4;701;702;703;704;,
+      4;705;706;707;708;,
+      4;709;710;711;712;,
+      4;713;714;715;716;,
+      4;717;718;719;720;,
+      4;721;722;723;724;,
+      4;725;726;727;728;,
+      4;729;730;731;732;,
+      4;733;734;735;736;,
+      4;737;738;739;740;,
+      3;741;742;743;,
+      3;744;745;746;,
+      4;747;748;749;750;,
+      4;751;752;753;754;,
+      4;755;756;757;758;,
+      4;759;760;761;762;,
+      4;763;764;765;766;,
+      4;767;768;769;770;,
+      4;771;772;773;774;,
+      4;775;776;777;778;,
+      4;779;780;781;782;,
+      4;783;784;785;786;,
+      4;787;788;789;790;,
+      4;791;792;793;794;,
+      4;795;796;797;798;,
+      4;799;800;801;802;,
+      3;803;804;805;,
+      3;806;807;808;,
+      4;809;810;811;812;,
+      4;813;814;815;816;,
+      4;817;818;819;820;,
+      4;821;822;823;824;,
+      4;825;826;827;828;,
+      4;829;830;831;832;,
+      4;833;834;835;836;,
+      4;837;838;839;840;,
+      4;841;842;843;844;,
+      4;845;846;847;848;,
+      4;849;850;851;852;,
+      4;853;854;855;856;,
+      4;857;858;859;860;,
+      4;861;862;863;864;,
+      3;865;866;867;,
+      3;868;869;870;,
+      4;871;872;873;874;,
+      4;875;876;877;878;,
+      4;879;880;881;882;,
+      4;883;884;885;886;,
+      4;887;888;889;890;,
+      4;891;892;893;894;,
+      4;895;896;897;898;,
+      4;899;900;901;902;,
+      4;903;904;905;906;,
+      4;907;908;909;910;,
+      4;911;912;913;914;,
+      4;915;916;917;918;,
+      4;919;920;921;922;,
+      4;923;924;925;926;,
+      3;927;928;929;,
+      3;930;931;932;,
+      4;933;934;935;936;,
+      4;937;938;939;940;,
+      4;941;942;943;944;,
+      4;945;946;947;948;,
+      4;949;950;951;952;,
+      4;953;954;955;956;,
+      4;957;958;959;960;,
+      4;961;962;963;964;,
+      4;965;966;967;968;,
+      4;969;970;971;972;,
+      4;973;974;975;976;,
+      4;977;978;979;980;,
+      4;981;982;983;984;,
+      4;985;986;987;988;,
+      3;989;990;991;,
+      3;992;993;994;,
+      4;995;996;997;998;,
+      4;999;1000;1001;1002;,
+      4;1003;1004;1005;1006;,
+      4;1007;1008;1009;1010;,
+      4;1011;1012;1013;1014;,
+      4;1015;1016;1017;1018;,
+      4;1019;1020;1021;1022;,
+      4;1023;1024;1025;1026;,
+      4;1027;1028;1029;1030;,
+      4;1031;1032;1033;1034;,
+      4;1035;1036;1037;1038;,
+      4;1039;1040;1041;1042;,
+      4;1043;1044;1045;1046;,
+      4;1047;1048;1049;1050;,
+      3;1051;1052;1053;,
+      3;1054;1055;1056;,
+      4;1057;1058;1059;1060;,
+      4;1061;1062;1063;1064;,
+      4;1065;1066;1067;1068;,
+      4;1069;1070;1071;1072;,
+      4;1073;1074;1075;1076;,
+      4;1077;1078;1079;1080;,
+      4;1081;1082;1083;1084;,
+      4;1085;1086;1087;1088;,
+      4;1089;1090;1091;1092;,
+      4;1093;1094;1095;1096;,
+      4;1097;1098;1099;1100;,
+      4;1101;1102;1103;1104;,
+      4;1105;1106;1107;1108;,
+      4;1109;1110;1111;1112;,
+      3;1113;1114;1115;,
+      3;1116;1117;1118;,
+      4;1119;1120;1121;1122;,
+      4;1123;1124;1125;1126;,
+      4;1127;1128;1129;1130;,
+      4;1131;1132;1133;1134;,
+      4;1135;1136;1137;1138;,
+      4;1139;1140;1141;1142;,
+      4;1143;1144;1145;1146;,
+      4;1147;1148;1149;1150;,
+      4;1151;1152;1153;1154;,
+      4;1155;1156;1157;1158;,
+      4;1159;1160;1161;1162;,
+      4;1163;1164;1165;1166;,
+      4;1167;1168;1169;1170;,
+      4;1171;1172;1173;1174;,
+      3;1175;1176;1177;,
+      3;1178;1179;1180;,
+      4;1181;1182;1183;1184;,
+      4;1185;1186;1187;1188;,
+      4;1189;1190;1191;1192;,
+      4;1193;1194;1195;1196;,
+      4;1197;1198;1199;1200;,
+      4;1201;1202;1203;1204;,
+      4;1205;1206;1207;1208;,
+      4;1209;1210;1211;1212;,
+      4;1213;1214;1215;1216;,
+      4;1217;1218;1219;1220;,
+      4;1221;1222;1223;1224;,
+      4;1225;1226;1227;1228;,
+      4;1229;1230;1231;1232;,
+      4;1233;1234;1235;1236;,
+      3;1237;1238;1239;,
+      3;1240;1241;1242;,
+      4;1243;1244;1245;1246;,
+      4;1247;1248;1249;1250;,
+      4;1251;1252;1253;1254;,
+      4;1255;1256;1257;1258;,
+      4;1259;1260;1261;1262;,
+      4;1263;1264;1265;1266;,
+      4;1267;1268;1269;1270;,
+      4;1271;1272;1273;1274;,
+      4;1275;1276;1277;1278;,
+      4;1279;1280;1281;1282;,
+      4;1283;1284;1285;1286;,
+      4;1287;1288;1289;1290;,
+      4;1291;1292;1293;1294;,
+      4;1295;1296;1297;1298;,
+      3;1299;1300;1301;,
+      3;1302;1303;1304;,
+      4;1305;1306;1307;1308;,
+      4;1309;1310;1311;1312;,
+      4;1313;1314;1315;1316;,
+      4;1317;1318;1319;1320;,
+      4;1321;1322;1323;1324;,
+      4;1325;1326;1327;1328;,
+      4;1329;1330;1331;1332;,
+      4;1333;1334;1335;1336;,
+      4;1337;1338;1339;1340;,
+      4;1341;1342;1343;1344;,
+      4;1345;1346;1347;1348;,
+      4;1349;1350;1351;1352;,
+      4;1353;1354;1355;1356;,
+      4;1357;1358;1359;1360;,
+      3;1361;1362;1363;,
+      3;1364;1365;1366;,
+      4;1367;1368;1369;1370;,
+      4;1371;1372;1373;1374;,
+      4;1375;1376;1377;1378;,
+      4;1379;1380;1381;1382;,
+      4;1383;1384;1385;1386;,
+      4;1387;1388;1389;1390;,
+      4;1391;1392;1393;1394;,
+      4;1395;1396;1397;1398;,
+      4;1399;1400;1401;1402;,
+      4;1403;1404;1405;1406;,
+      4;1407;1408;1409;1410;,
+      4;1411;1412;1413;1414;,
+      4;1415;1416;1417;1418;,
+      4;1419;1420;1421;1422;,
+      3;1423;1424;1425;,
+      3;1426;1427;1428;,
+      4;1429;1430;1431;1432;,
+      4;1433;1434;1435;1436;,
+      4;1437;1438;1439;1440;,
+      4;1441;1442;1443;1444;,
+      4;1445;1446;1447;1448;,
+      4;1449;1450;1451;1452;,
+      4;1453;1454;1455;1456;,
+      4;1457;1458;1459;1460;,
+      4;1461;1462;1463;1464;,
+      4;1465;1466;1467;1468;,
+      4;1469;1470;1471;1472;,
+      4;1473;1474;1475;1476;,
+      4;1477;1478;1479;1480;,
+      4;1481;1482;1483;1484;,
+      3;1485;1486;1487;,
+      3;1488;1489;1490;,
+      4;1491;1492;1493;1494;,
+      4;1495;1496;1497;1498;,
+      4;1499;1500;1501;1502;,
+      4;1503;1504;1505;1506;,
+      4;1507;1508;1509;1510;,
+      4;1511;1512;1513;1514;,
+      4;1515;1516;1517;1518;,
+      4;1519;1520;1521;1522;,
+      4;1523;1524;1525;1526;,
+      4;1527;1528;1529;1530;,
+      4;1531;1532;1533;1534;,
+      4;1535;1536;1537;1538;,
+      4;1539;1540;1541;1542;,
+      4;1543;1544;1545;1546;,
+      3;1547;1548;1549;,
+      3;1550;1551;1552;,
+      4;1553;1554;1555;1556;,
+      4;1557;1558;1559;1560;,
+      4;1561;1562;1563;1564;,
+      4;1565;1566;1567;1568;,
+      4;1569;1570;1571;1572;,
+      4;1573;1574;1575;1576;,
+      4;1577;1578;1579;1580;,
+      4;1581;1582;1583;1584;,
+      4;1585;1586;1587;1588;,
+      4;1589;1590;1591;1592;,
+      4;1593;1594;1595;1596;,
+      4;1597;1598;1599;1600;,
+      4;1601;1602;1603;1604;,
+      4;1605;1606;1607;1608;,
+      3;1609;1610;1611;,
+      3;1612;1613;1614;,
+      4;1615;1616;1617;1618;,
+      4;1619;1620;1621;1622;,
+      4;1623;1624;1625;1626;,
+      4;1627;1628;1629;1630;,
+      4;1631;1632;1633;1634;,
+      4;1635;1636;1637;1638;,
+      4;1639;1640;1641;1642;,
+      4;1643;1644;1645;1646;,
+      4;1647;1648;1649;1650;,
+      4;1651;1652;1653;1654;,
+      4;1655;1656;1657;1658;,
+      4;1659;1660;1661;1662;,
+      4;1663;1664;1665;1666;,
+      4;1667;1668;1669;1670;,
+      3;1671;1672;1673;,
+      3;1674;1675;1676;,
+      4;1677;1678;1679;1680;,
+      4;1681;1682;1683;1684;,
+      4;1685;1686;1687;1688;,
+      4;1689;1690;1691;1692;,
+      4;1693;1694;1695;1696;,
+      4;1697;1698;1699;1700;,
+      4;1701;1702;1703;1704;,
+      4;1705;1706;1707;1708;,
+      4;1709;1710;1711;1712;,
+      4;1713;1714;1715;1716;,
+      4;1717;1718;1719;1720;,
+      4;1721;1722;1723;1724;,
+      4;1725;1726;1727;1728;,
+      4;1729;1730;1731;1732;,
+      3;1733;1734;1735;,
+      3;1736;1737;1738;,
+      4;1739;1740;1741;1742;,
+      4;1743;1744;1745;1746;,
+      4;1747;1748;1749;1750;,
+      4;1751;1752;1753;1754;,
+      4;1755;1756;1757;1758;,
+      4;1759;1760;1761;1762;,
+      4;1763;1764;1765;1766;,
+      4;1767;1768;1769;1770;,
+      4;1771;1772;1773;1774;,
+      4;1775;1776;1777;1778;,
+      4;1779;1780;1781;1782;,
+      4;1783;1784;1785;1786;,
+      4;1787;1788;1789;1790;,
+      4;1791;1792;1793;1794;,
+      3;1795;1796;1797;,
+      3;1798;1799;1800;,
+      4;1801;1802;1803;1804;,
+      4;1805;1806;1807;1808;,
+      4;1809;1810;1811;1812;,
+      4;1813;1814;1815;1816;,
+      4;1817;1818;1819;1820;,
+      4;1821;1822;1823;1824;,
+      4;1825;1826;1827;1828;,
+      4;1829;1830;1831;1832;,
+      4;1833;1834;1835;1836;,
+      4;1837;1838;1839;1840;,
+      4;1841;1842;1843;1844;,
+      4;1845;1846;1847;1848;,
+      4;1849;1850;1851;1852;,
+      4;1853;1854;1855;1856;,
+      3;1857;1858;1859;,
+      3;1860;1861;1862;,
+      4;1863;1864;1865;1866;,
+      4;1867;1868;1869;1870;,
+      4;1871;1872;1873;1874;,
+      4;1875;1876;1877;1878;,
+      4;1879;1880;1881;1882;,
+      4;1883;1884;1885;1886;,
+      4;1887;1888;1889;1890;,
+      4;1891;1892;1893;1894;,
+      4;1895;1896;1897;1898;,
+      4;1899;1900;1901;1902;,
+      4;1903;1904;1905;1906;,
+      4;1907;1908;1909;1910;,
+      4;1911;1912;1913;1914;,
+      4;1915;1916;1917;1918;,
+      3;1919;1920;1921;,
+      3;1922;1923;1924;,
+      4;1925;1926;1927;1928;,
+      4;1929;1930;1931;1932;,
+      4;1933;1934;1935;1936;,
+      4;1937;1938;1939;1940;,
+      4;1941;1942;1943;1944;,
+      4;1945;1946;1947;1948;,
+      4;1949;1950;1951;1952;,
+      4;1953;1954;1955;1956;,
+      4;1957;1958;1959;1960;,
+      4;1961;1962;1963;1964;,
+      4;1965;1966;1967;1968;,
+      4;1969;1970;1971;1972;,
+      4;1973;1974;1975;1976;,
+      4;1977;1978;1979;1980;,
+      3;1981;1982;1983;;
+      MeshNormals { //Sphere_001 Normals
+        1984;
+         0.098012; 0.009653;-0.995138;,
+         0.098012; 0.009653;-0.995138;,
+         0.098012; 0.009653;-0.995138;,
+         0.290166; 0.028578;-0.956550;,
+         0.290166; 0.028578;-0.956550;,
+         0.290166; 0.028578;-0.956550;,
+         0.290166; 0.028578;-0.956550;,
+         0.470890; 0.046377;-0.880972;,
+         0.470890; 0.046377;-0.880972;,
+         0.470890; 0.046377;-0.880972;,
+         0.470890; 0.046377;-0.880972;,
+         0.633158; 0.062359;-0.771506;,
+         0.633158; 0.062359;-0.771506;,
+         0.633158; 0.062359;-0.771506;,
+         0.633158; 0.062359;-0.771506;,
+         0.770781; 0.075914;-0.632562;,
+         0.770781; 0.075914;-0.632562;,
+         0.770781; 0.075914;-0.632562;,
+         0.770781; 0.075914;-0.632562;,
+         0.878613; 0.086534;-0.469629;,
+         0.878613; 0.086534;-0.469629;,
+         0.878613; 0.086534;-0.469629;,
+         0.878613; 0.086534;-0.469629;,
+         0.952718; 0.093832;-0.289003;,
+         0.952718; 0.093832;-0.289003;,
+         0.952718; 0.093832;-0.289003;,
+         0.952718; 0.093832;-0.289003;,
+         0.990439; 0.097545;-0.097548;,
+         0.990439; 0.097545;-0.097548;,
+         0.990439; 0.097545;-0.097548;,
+         0.990439; 0.097545;-0.097548;,
+         0.990439; 0.097546; 0.097548;,
+         0.990439; 0.097546; 0.097548;,
+         0.990439; 0.097546; 0.097548;,
+         0.990439; 0.097546; 0.097548;,
+         0.952718; 0.093832; 0.289004;,
+         0.952718; 0.093832; 0.289004;,
+         0.952718; 0.093832; 0.289004;,
+         0.952718; 0.093832; 0.289004;,
+         0.878613; 0.086533; 0.469628;,
+         0.878613; 0.086533; 0.469628;,
+         0.878613; 0.086533; 0.469628;,
+         0.878613; 0.086533; 0.469628;,
+         0.770780; 0.075914; 0.632562;,
+         0.770780; 0.075914; 0.632562;,
+         0.770780; 0.075914; 0.632562;,
+         0.770780; 0.075914; 0.632562;,
+         0.633158; 0.062358; 0.771506;,
+         0.633158; 0.062358; 0.771506;,
+         0.633158; 0.062358; 0.771506;,
+         0.633158; 0.062358; 0.771506;,
+         0.470890; 0.046376; 0.880972;,
+         0.470890; 0.046376; 0.880972;,
+         0.470890; 0.046376; 0.880972;,
+         0.470890; 0.046376; 0.880972;,
+         0.290166; 0.028578; 0.956549;,
+         0.290166; 0.028578; 0.956549;,
+         0.290166; 0.028578; 0.956549;,
+         0.290166; 0.028578; 0.956549;,
+         0.098013; 0.009653; 0.995138;,
+         0.098013; 0.009653; 0.995138;,
+         0.098013; 0.009653; 0.995138;,
+         0.094246; 0.028589; 0.995138;,
+         0.094246; 0.028589; 0.995138;,
+         0.094246; 0.028589; 0.995138;,
+         0.279015; 0.084638; 0.956549;,
+         0.279015; 0.084638; 0.956549;,
+         0.279015; 0.084638; 0.956549;,
+         0.279015; 0.084638; 0.956549;,
+         0.452793; 0.137354; 0.880972;,
+         0.452793; 0.137354; 0.880972;,
+         0.452793; 0.137354; 0.880972;,
+         0.452793; 0.137354; 0.880972;,
+         0.608827; 0.184686; 0.771506;,
+         0.608827; 0.184686; 0.771506;,
+         0.608827; 0.184686; 0.771506;,
+         0.608827; 0.184686; 0.771506;,
+         0.741159; 0.224828; 0.632563;,
+         0.741159; 0.224828; 0.632563;,
+         0.741159; 0.224828; 0.632563;,
+         0.741159; 0.224828; 0.632563;,
+         0.844848; 0.256282; 0.469628;,
+         0.844848; 0.256282; 0.469628;,
+         0.844848; 0.256282; 0.469628;,
+         0.844848; 0.256282; 0.469628;,
+         0.916106; 0.277898; 0.289004;,
+         0.916106; 0.277898; 0.289004;,
+         0.916106; 0.277898; 0.289004;,
+         0.916106; 0.277898; 0.289004;,
+         0.952376; 0.288900; 0.097550;,
+         0.952376; 0.288900; 0.097550;,
+         0.952376; 0.288900; 0.097550;,
+         0.952376; 0.288900; 0.097550;,
+         0.952376; 0.288900;-0.097550;,
+         0.952376; 0.288900;-0.097550;,
+         0.952376; 0.288900;-0.097550;,
+         0.952376; 0.288900;-0.097550;,
+         0.916106; 0.277898;-0.289004;,
+         0.916106; 0.277898;-0.289004;,
+         0.916106; 0.277898;-0.289004;,
+         0.916106; 0.277898;-0.289004;,
+         0.844848; 0.256282;-0.469629;,
+         0.844848; 0.256282;-0.469629;,
+         0.844848; 0.256282;-0.469629;,
+         0.844848; 0.256282;-0.469629;,
+         0.741159; 0.224828;-0.632562;,
+         0.741159; 0.224828;-0.632562;,
+         0.741159; 0.224828;-0.632562;,
+         0.741159; 0.224828;-0.632562;,
+         0.608827; 0.184686;-0.771506;,
+         0.608827; 0.184686;-0.771506;,
+         0.608827; 0.184686;-0.771506;,
+         0.608827; 0.184686;-0.771506;,
+         0.452793; 0.137353;-0.880972;,
+         0.452793; 0.137353;-0.880972;,
+         0.452793; 0.137353;-0.880972;,
+         0.452793; 0.137353;-0.880972;,
+         0.279015; 0.084638;-0.956549;,
+         0.279015; 0.084638;-0.956549;,
+         0.279015; 0.084638;-0.956549;,
+         0.279015; 0.084638;-0.956549;,
+         0.094246; 0.028589;-0.995138;,
+         0.094246; 0.028589;-0.995138;,
+         0.094246; 0.028589;-0.995138;,
+         0.086857; 0.046426;-0.995138;,
+         0.086857; 0.046426;-0.995138;,
+         0.086857; 0.046426;-0.995138;,
+         0.257142; 0.137445;-0.956549;,
+         0.257142; 0.137445;-0.956549;,
+         0.257142; 0.137445;-0.956549;,
+         0.257142; 0.137445;-0.956549;,
+         0.417297; 0.223050;-0.880972;,
+         0.417297; 0.223050;-0.880972;,
+         0.417297; 0.223050;-0.880972;,
+         0.417297; 0.223050;-0.880972;,
+         0.561098; 0.299913;-0.771506;,
+         0.561098; 0.299913;-0.771506;,
+         0.561098; 0.299913;-0.771506;,
+         0.561098; 0.299913;-0.771506;,
+         0.683057; 0.365101;-0.632562;,
+         0.683057; 0.365101;-0.632562;,
+         0.683057; 0.365101;-0.632562;,
+         0.683057; 0.365101;-0.632562;,
+         0.778617; 0.416179;-0.469629;,
+         0.778617; 0.416179;-0.469629;,
+         0.778617; 0.416179;-0.469629;,
+         0.778617; 0.416179;-0.469629;,
+         0.844288; 0.451281;-0.289004;,
+         0.844288; 0.451281;-0.289004;,
+         0.844288; 0.451281;-0.289004;,
+         0.844288; 0.451281;-0.289004;,
+         0.877715; 0.469149;-0.097549;,
+         0.877715; 0.469149;-0.097549;,
+         0.877715; 0.469149;-0.097549;,
+         0.877715; 0.469149;-0.097549;,
+         0.877715; 0.469149; 0.097549;,
+         0.877715; 0.469149; 0.097549;,
+         0.877715; 0.469149; 0.097549;,
+         0.877715; 0.469149; 0.097549;,
+         0.844288; 0.451281; 0.289004;,
+         0.844288; 0.451281; 0.289004;,
+         0.844288; 0.451281; 0.289004;,
+         0.844288; 0.451281; 0.289004;,
+         0.778617; 0.416179; 0.469628;,
+         0.778617; 0.416179; 0.469628;,
+         0.778617; 0.416179; 0.469628;,
+         0.778617; 0.416179; 0.469628;,
+         0.683056; 0.365101; 0.632562;,
+         0.683056; 0.365101; 0.632562;,
+         0.683056; 0.365101; 0.632562;,
+         0.683056; 0.365101; 0.632562;,
+         0.561098; 0.299913; 0.771506;,
+         0.561098; 0.299913; 0.771506;,
+         0.561098; 0.299913; 0.771506;,
+         0.561098; 0.299913; 0.771506;,
+         0.417297; 0.223050; 0.880972;,
+         0.417297; 0.223050; 0.880972;,
+         0.417297; 0.223050; 0.880972;,
+         0.417297; 0.223050; 0.880972;,
+         0.257142; 0.137445; 0.956549;,
+         0.257142; 0.137445; 0.956549;,
+         0.257142; 0.137445; 0.956549;,
+         0.257142; 0.137445; 0.956549;,
+         0.086858; 0.046426; 0.995138;,
+         0.086858; 0.046426; 0.995138;,
+         0.086858; 0.046426; 0.995138;,
+         0.076131; 0.062480; 0.995138;,
+         0.076131; 0.062480; 0.995138;,
+         0.076131; 0.062480; 0.995138;,
+         0.225387; 0.184970; 0.956549;,
+         0.225387; 0.184970; 0.956549;,
+         0.225387; 0.184970; 0.956549;,
+         0.225387; 0.184970; 0.956549;,
+         0.365764; 0.300175; 0.880972;,
+         0.365764; 0.300175; 0.880972;,
+         0.365764; 0.300175; 0.880972;,
+         0.365764; 0.300175; 0.880972;,
+         0.491806; 0.403615; 0.771506;,
+         0.491806; 0.403615; 0.771506;,
+         0.491806; 0.403615; 0.771506;,
+         0.491806; 0.403615; 0.771506;,
+         0.598704; 0.491344; 0.632562;,
+         0.598704; 0.491344; 0.632562;,
+         0.598704; 0.491344; 0.632562;,
+         0.598704; 0.491344; 0.632562;,
+         0.682463; 0.560083; 0.469628;,
+         0.682463; 0.560083; 0.469628;,
+         0.682463; 0.560083; 0.469628;,
+         0.682463; 0.560083; 0.469628;,
+         0.740024; 0.607322; 0.289004;,
+         0.740024; 0.607322; 0.289004;,
+         0.740024; 0.607322; 0.289004;,
+         0.740024; 0.607322; 0.289004;,
+         0.769324; 0.631368; 0.097549;,
+         0.769324; 0.631368; 0.097549;,
+         0.769324; 0.631368; 0.097549;,
+         0.769324; 0.631368; 0.097549;,
+         0.769324; 0.631368;-0.097549;,
+         0.769324; 0.631368;-0.097549;,
+         0.769324; 0.631368;-0.097549;,
+         0.769324; 0.631368;-0.097549;,
+         0.740024; 0.607323;-0.289004;,
+         0.740024; 0.607323;-0.289004;,
+         0.740024; 0.607323;-0.289004;,
+         0.740024; 0.607323;-0.289004;,
+         0.682463; 0.560083;-0.469629;,
+         0.682463; 0.560083;-0.469629;,
+         0.682463; 0.560083;-0.469629;,
+         0.682463; 0.560083;-0.469629;,
+         0.598704; 0.491344;-0.632562;,
+         0.598704; 0.491344;-0.632562;,
+         0.598704; 0.491344;-0.632562;,
+         0.598704; 0.491344;-0.632562;,
+         0.491806; 0.403615;-0.771506;,
+         0.491806; 0.403615;-0.771506;,
+         0.491806; 0.403615;-0.771506;,
+         0.491806; 0.403615;-0.771506;,
+         0.365764; 0.300175;-0.880972;,
+         0.365764; 0.300175;-0.880972;,
+         0.365764; 0.300175;-0.880972;,
+         0.365764; 0.300175;-0.880972;,
+         0.225387; 0.184970;-0.956550;,
+         0.225387; 0.184970;-0.956550;,
+         0.225387; 0.184970;-0.956550;,
+         0.225387; 0.184970;-0.956550;,
+         0.076131; 0.062479;-0.995138;,
+         0.076131; 0.062479;-0.995138;,
+         0.076131; 0.062479;-0.995138;,
+         0.062479; 0.076131;-0.995138;,
+         0.062479; 0.076131;-0.995138;,
+         0.062479; 0.076131;-0.995138;,
+         0.184970; 0.225387;-0.956549;,
+         0.184970; 0.225387;-0.956549;,
+         0.184970; 0.225387;-0.956549;,
+         0.184970; 0.225387;-0.956549;,
+         0.300175; 0.365764;-0.880972;,
+         0.300175; 0.365764;-0.880972;,
+         0.300175; 0.365764;-0.880972;,
+         0.300175; 0.365764;-0.880972;,
+         0.403615; 0.491806;-0.771506;,
+         0.403615; 0.491806;-0.771506;,
+         0.403615; 0.491806;-0.771506;,
+         0.403615; 0.491806;-0.771506;,
+         0.491344; 0.598704;-0.632562;,
+         0.491344; 0.598704;-0.632562;,
+         0.491344; 0.598704;-0.632562;,
+         0.491344; 0.598704;-0.632562;,
+         0.560083; 0.682463;-0.469628;,
+         0.560083; 0.682463;-0.469628;,
+         0.560083; 0.682463;-0.469628;,
+         0.560083; 0.682463;-0.469628;,
+         0.607322; 0.740025;-0.289004;,
+         0.607322; 0.740025;-0.289004;,
+         0.607322; 0.740025;-0.289004;,
+         0.607322; 0.740025;-0.289004;,
+         0.631367; 0.769324;-0.097549;,
+         0.631367; 0.769324;-0.097549;,
+         0.631367; 0.769324;-0.097549;,
+         0.631367; 0.769324;-0.097549;,
+         0.631367; 0.769324; 0.097549;,
+         0.631367; 0.769324; 0.097549;,
+         0.631367; 0.769324; 0.097549;,
+         0.631367; 0.769324; 0.097549;,
+         0.607322; 0.740025; 0.289004;,
+         0.607322; 0.740025; 0.289004;,
+         0.607322; 0.740025; 0.289004;,
+         0.607322; 0.740025; 0.289004;,
+         0.560083; 0.682463; 0.469628;,
+         0.560083; 0.682463; 0.469628;,
+         0.560083; 0.682463; 0.469628;,
+         0.560083; 0.682463; 0.469628;,
+         0.491344; 0.598704; 0.632562;,
+         0.491344; 0.598704; 0.632562;,
+         0.491344; 0.598704; 0.632562;,
+         0.491344; 0.598704; 0.632562;,
+         0.403615; 0.491806; 0.771506;,
+         0.403615; 0.491806; 0.771506;,
+         0.403615; 0.491806; 0.771506;,
+         0.403615; 0.491806; 0.771506;,
+         0.300175; 0.365764; 0.880972;,
+         0.300175; 0.365764; 0.880972;,
+         0.300175; 0.365764; 0.880972;,
+         0.300175; 0.365764; 0.880972;,
+         0.184970; 0.225387; 0.956549;,
+         0.184970; 0.225387; 0.956549;,
+         0.184970; 0.225387; 0.956549;,
+         0.184970; 0.225387; 0.956549;,
+         0.062479; 0.076131; 0.995138;,
+         0.062479; 0.076131; 0.995138;,
+         0.062479; 0.076131; 0.995138;,
+         0.046426; 0.086858; 0.995138;,
+         0.046426; 0.086858; 0.995138;,
+         0.046426; 0.086858; 0.995138;,
+         0.137445; 0.257142; 0.956549;,
+         0.137445; 0.257142; 0.956549;,
+         0.137445; 0.257142; 0.956549;,
+         0.137445; 0.257142; 0.956549;,
+         0.223050; 0.417297; 0.880972;,
+         0.223050; 0.417297; 0.880972;,
+         0.223050; 0.417297; 0.880972;,
+         0.223050; 0.417297; 0.880972;,
+         0.299913; 0.561098; 0.771506;,
+         0.299913; 0.561098; 0.771506;,
+         0.299913; 0.561098; 0.771506;,
+         0.299913; 0.561098; 0.771506;,
+         0.365101; 0.683056; 0.632562;,
+         0.365101; 0.683056; 0.632562;,
+         0.365101; 0.683056; 0.632562;,
+         0.365101; 0.683056; 0.632562;,
+         0.416179; 0.778617; 0.469628;,
+         0.416179; 0.778617; 0.469628;,
+         0.416179; 0.778617; 0.469628;,
+         0.416179; 0.778617; 0.469628;,
+         0.451281; 0.844288; 0.289004;,
+         0.451281; 0.844288; 0.289004;,
+         0.451281; 0.844288; 0.289004;,
+         0.451281; 0.844288; 0.289004;,
+         0.469148; 0.877715; 0.097549;,
+         0.469148; 0.877715; 0.097549;,
+         0.469148; 0.877715; 0.097549;,
+         0.469148; 0.877715; 0.097549;,
+         0.469148; 0.877715;-0.097549;,
+         0.469148; 0.877715;-0.097549;,
+         0.469148; 0.877715;-0.097549;,
+         0.469148; 0.877715;-0.097549;,
+         0.451281; 0.844288;-0.289004;,
+         0.451281; 0.844288;-0.289004;,
+         0.451281; 0.844288;-0.289004;,
+         0.451281; 0.844288;-0.289004;,
+         0.416179; 0.778617;-0.469628;,
+         0.416179; 0.778617;-0.469628;,
+         0.416179; 0.778617;-0.469628;,
+         0.416179; 0.778617;-0.469628;,
+         0.365101; 0.683057;-0.632562;,
+         0.365101; 0.683057;-0.632562;,
+         0.365101; 0.683057;-0.632562;,
+         0.365101; 0.683057;-0.632562;,
+         0.299913; 0.561098;-0.771506;,
+         0.299913; 0.561098;-0.771506;,
+         0.299913; 0.561098;-0.771506;,
+         0.299913; 0.561098;-0.771506;,
+         0.223050; 0.417297;-0.880972;,
+         0.223050; 0.417297;-0.880972;,
+         0.223050; 0.417297;-0.880972;,
+         0.223050; 0.417297;-0.880972;,
+         0.137445; 0.257142;-0.956549;,
+         0.137445; 0.257142;-0.956549;,
+         0.137445; 0.257142;-0.956549;,
+         0.137445; 0.257142;-0.956549;,
+         0.046426; 0.086857;-0.995138;,
+         0.046426; 0.086857;-0.995138;,
+         0.046426; 0.086857;-0.995138;,
+         0.028589; 0.094246;-0.995138;,
+         0.028589; 0.094246;-0.995138;,
+         0.028589; 0.094246;-0.995138;,
+         0.084638; 0.279015;-0.956549;,
+         0.084638; 0.279015;-0.956549;,
+         0.084638; 0.279015;-0.956549;,
+         0.084638; 0.279015;-0.956549;,
+         0.137353; 0.452794;-0.880972;,
+         0.137353; 0.452794;-0.880972;,
+         0.137353; 0.452794;-0.880972;,
+         0.137353; 0.452794;-0.880972;,
+         0.184685; 0.608826;-0.771506;,
+         0.184685; 0.608826;-0.771506;,
+         0.184685; 0.608826;-0.771506;,
+         0.184685; 0.608826;-0.771506;,
+         0.224828; 0.741160;-0.632562;,
+         0.224828; 0.741160;-0.632562;,
+         0.224828; 0.741160;-0.632562;,
+         0.224828; 0.741160;-0.632562;,
+         0.256282; 0.844848;-0.469628;,
+         0.256282; 0.844848;-0.469628;,
+         0.256282; 0.844848;-0.469628;,
+         0.256282; 0.844848;-0.469628;,
+         0.277898; 0.916106;-0.289003;,
+         0.277898; 0.916106;-0.289003;,
+         0.277898; 0.916106;-0.289003;,
+         0.277898; 0.916106;-0.289003;,
+         0.288900; 0.952377;-0.097549;,
+         0.288900; 0.952377;-0.097549;,
+         0.288900; 0.952377;-0.097549;,
+         0.288900; 0.952377;-0.097549;,
+         0.288900; 0.952376; 0.097549;,
+         0.288900; 0.952376; 0.097549;,
+         0.288900; 0.952376; 0.097549;,
+         0.288900; 0.952376; 0.097549;,
+         0.277898; 0.916106; 0.289004;,
+         0.277898; 0.916106; 0.289004;,
+         0.277898; 0.916106; 0.289004;,
+         0.277898; 0.916106; 0.289004;,
+         0.256282; 0.844848; 0.469628;,
+         0.256282; 0.844848; 0.469628;,
+         0.256282; 0.844848; 0.469628;,
+         0.256282; 0.844848; 0.469628;,
+         0.224828; 0.741159; 0.632562;,
+         0.224828; 0.741159; 0.632562;,
+         0.224828; 0.741159; 0.632562;,
+         0.224828; 0.741159; 0.632562;,
+         0.184686; 0.608827; 0.771506;,
+         0.184686; 0.608827; 0.771506;,
+         0.184686; 0.608827; 0.771506;,
+         0.184686; 0.608827; 0.771506;,
+         0.137353; 0.452793; 0.880972;,
+         0.137353; 0.452793; 0.880972;,
+         0.137353; 0.452793; 0.880972;,
+         0.137353; 0.452793; 0.880972;,
+         0.084638; 0.279015; 0.956549;,
+         0.084638; 0.279015; 0.956549;,
+         0.084638; 0.279015; 0.956549;,
+         0.084638; 0.279015; 0.956549;,
+         0.028589; 0.094246; 0.995138;,
+         0.028589; 0.094246; 0.995138;,
+         0.028589; 0.094246; 0.995138;,
+         0.009653; 0.098013; 0.995138;,
+         0.009653; 0.098013; 0.995138;,
+         0.009653; 0.098013; 0.995138;,
+         0.028579; 0.290166; 0.956549;,
+         0.028579; 0.290166; 0.956549;,
+         0.028579; 0.290166; 0.956549;,
+         0.028579; 0.290166; 0.956549;,
+         0.046378; 0.470890; 0.880972;,
+         0.046378; 0.470890; 0.880972;,
+         0.046378; 0.470890; 0.880972;,
+         0.046378; 0.470890; 0.880972;,
+         0.062360; 0.633159; 0.771506;,
+         0.062360; 0.633159; 0.771506;,
+         0.062360; 0.633159; 0.771506;,
+         0.062360; 0.633159; 0.771506;,
+         0.075915; 0.770780; 0.632562;,
+         0.075915; 0.770780; 0.632562;,
+         0.075915; 0.770780; 0.632562;,
+         0.075915; 0.770780; 0.632562;,
+         0.086536; 0.878613; 0.469628;,
+         0.086536; 0.878613; 0.469628;,
+         0.086536; 0.878613; 0.469628;,
+         0.086536; 0.878613; 0.469628;,
+         0.093835; 0.952718; 0.289004;,
+         0.093835; 0.952718; 0.289004;,
+         0.093835; 0.952718; 0.289004;,
+         0.093835; 0.952718; 0.289004;,
+         0.097549; 0.990438; 0.097549;,
+         0.097549; 0.990438; 0.097549;,
+         0.097549; 0.990438; 0.097549;,
+         0.097549; 0.990438; 0.097549;,
+         0.097549; 0.990438;-0.097549;,
+         0.097549; 0.990438;-0.097549;,
+         0.097549; 0.990438;-0.097549;,
+         0.097549; 0.990438;-0.097549;,
+         0.093834; 0.952718;-0.289004;,
+         0.093834; 0.952718;-0.289004;,
+         0.093834; 0.952718;-0.289004;,
+         0.093834; 0.952718;-0.289004;,
+         0.086536; 0.878613;-0.469628;,
+         0.086536; 0.878613;-0.469628;,
+         0.086536; 0.878613;-0.469628;,
+         0.086536; 0.878613;-0.469628;,
+         0.075915; 0.770780;-0.632562;,
+         0.075915; 0.770780;-0.632562;,
+         0.075915; 0.770780;-0.632562;,
+         0.075915; 0.770780;-0.632562;,
+         0.062360; 0.633158;-0.771506;,
+         0.062360; 0.633158;-0.771506;,
+         0.062360; 0.633158;-0.771506;,
+         0.062360; 0.633158;-0.771506;,
+         0.046378; 0.470890;-0.880972;,
+         0.046378; 0.470890;-0.880972;,
+         0.046378; 0.470890;-0.880972;,
+         0.046378; 0.470890;-0.880972;,
+         0.028579; 0.290166;-0.956550;,
+         0.028579; 0.290166;-0.956550;,
+         0.028579; 0.290166;-0.956550;,
+         0.028579; 0.290166;-0.956550;,
+         0.009653; 0.098012;-0.995138;,
+         0.009653; 0.098012;-0.995138;,
+         0.009653; 0.098012;-0.995138;,
+        -0.009653; 0.098012;-0.995138;,
+        -0.009653; 0.098012;-0.995138;,
+        -0.009653; 0.098012;-0.995138;,
+        -0.028579; 0.290166;-0.956549;,
+        -0.028579; 0.290166;-0.956549;,
+        -0.028579; 0.290166;-0.956549;,
+        -0.028579; 0.290166;-0.956549;,
+        -0.046379; 0.470890;-0.880972;,
+        -0.046379; 0.470890;-0.880972;,
+        -0.046379; 0.470890;-0.880972;,
+        -0.046379; 0.470890;-0.880972;,
+        -0.062361; 0.633158;-0.771506;,
+        -0.062361; 0.633158;-0.771506;,
+        -0.062361; 0.633158;-0.771506;,
+        -0.062361; 0.633158;-0.771506;,
+        -0.075915; 0.770780;-0.632562;,
+        -0.075915; 0.770780;-0.632562;,
+        -0.075915; 0.770780;-0.632562;,
+        -0.075915; 0.770780;-0.632562;,
+        -0.086536; 0.878613;-0.469629;,
+        -0.086536; 0.878613;-0.469629;,
+        -0.086536; 0.878613;-0.469629;,
+        -0.086536; 0.878613;-0.469629;,
+        -0.093835; 0.952718;-0.289004;,
+        -0.093835; 0.952718;-0.289004;,
+        -0.093835; 0.952718;-0.289004;,
+        -0.093835; 0.952718;-0.289004;,
+        -0.097550; 0.990438;-0.097549;,
+        -0.097550; 0.990438;-0.097549;,
+        -0.097550; 0.990438;-0.097549;,
+        -0.097550; 0.990438;-0.097549;,
+        -0.097550; 0.990438; 0.097549;,
+        -0.097550; 0.990438; 0.097549;,
+        -0.097550; 0.990438; 0.097549;,
+        -0.097550; 0.990438; 0.097549;,
+        -0.093835; 0.952718; 0.289004;,
+        -0.093835; 0.952718; 0.289004;,
+        -0.093835; 0.952718; 0.289004;,
+        -0.093835; 0.952718; 0.289004;,
+        -0.086536; 0.878613; 0.469629;,
+        -0.086536; 0.878613; 0.469629;,
+        -0.086536; 0.878613; 0.469629;,
+        -0.086536; 0.878613; 0.469629;,
+        -0.075915; 0.770780; 0.632562;,
+        -0.075915; 0.770780; 0.632562;,
+        -0.075915; 0.770780; 0.632562;,
+        -0.075915; 0.770780; 0.632562;,
+        -0.062361; 0.633158; 0.771506;,
+        -0.062361; 0.633158; 0.771506;,
+        -0.062361; 0.633158; 0.771506;,
+        -0.062361; 0.633158; 0.771506;,
+        -0.046379; 0.470890; 0.880972;,
+        -0.046379; 0.470890; 0.880972;,
+        -0.046379; 0.470890; 0.880972;,
+        -0.046379; 0.470890; 0.880972;,
+        -0.028579; 0.290166; 0.956549;,
+        -0.028579; 0.290166; 0.956549;,
+        -0.028579; 0.290166; 0.956549;,
+        -0.028579; 0.290166; 0.956549;,
+        -0.009653; 0.098013; 0.995138;,
+        -0.009653; 0.098013; 0.995138;,
+        -0.009653; 0.098013; 0.995138;,
+        -0.028589; 0.094246; 0.995138;,
+        -0.028589; 0.094246; 0.995138;,
+        -0.028589; 0.094246; 0.995138;,
+        -0.084638; 0.279015; 0.956549;,
+        -0.084638; 0.279015; 0.956549;,
+        -0.084638; 0.279015; 0.956549;,
+        -0.084638; 0.279015; 0.956549;,
+        -0.137354; 0.452794; 0.880972;,
+        -0.137354; 0.452794; 0.880972;,
+        -0.137354; 0.452794; 0.880972;,
+        -0.137354; 0.452794; 0.880972;,
+        -0.184686; 0.608827; 0.771506;,
+        -0.184686; 0.608827; 0.771506;,
+        -0.184686; 0.608827; 0.771506;,
+        -0.184686; 0.608827; 0.771506;,
+        -0.224828; 0.741159; 0.632562;,
+        -0.224828; 0.741159; 0.632562;,
+        -0.224828; 0.741159; 0.632562;,
+        -0.224828; 0.741159; 0.632562;,
+        -0.256282; 0.844848; 0.469629;,
+        -0.256282; 0.844848; 0.469629;,
+        -0.256282; 0.844848; 0.469629;,
+        -0.256282; 0.844848; 0.469629;,
+        -0.277898; 0.916106; 0.289004;,
+        -0.277898; 0.916106; 0.289004;,
+        -0.277898; 0.916106; 0.289004;,
+        -0.277898; 0.916106; 0.289004;,
+        -0.288900; 0.952376; 0.097549;,
+        -0.288900; 0.952376; 0.097549;,
+        -0.288900; 0.952376; 0.097549;,
+        -0.288900; 0.952376; 0.097549;,
+        -0.288901; 0.952376;-0.097549;,
+        -0.288901; 0.952376;-0.097549;,
+        -0.288901; 0.952376;-0.097549;,
+        -0.288901; 0.952376;-0.097549;,
+        -0.277898; 0.916106;-0.289004;,
+        -0.277898; 0.916106;-0.289004;,
+        -0.277898; 0.916106;-0.289004;,
+        -0.277898; 0.916106;-0.289004;,
+        -0.256282; 0.844848;-0.469629;,
+        -0.256282; 0.844848;-0.469629;,
+        -0.256282; 0.844848;-0.469629;,
+        -0.256282; 0.844848;-0.469629;,
+        -0.224828; 0.741160;-0.632562;,
+        -0.224828; 0.741160;-0.632562;,
+        -0.224828; 0.741160;-0.632562;,
+        -0.224828; 0.741160;-0.632562;,
+        -0.184686; 0.608826;-0.771506;,
+        -0.184686; 0.608826;-0.771506;,
+        -0.184686; 0.608826;-0.771506;,
+        -0.184686; 0.608826;-0.771506;,
+        -0.137353; 0.452794;-0.880972;,
+        -0.137353; 0.452794;-0.880972;,
+        -0.137353; 0.452794;-0.880972;,
+        -0.137353; 0.452794;-0.880972;,
+        -0.084638; 0.279015;-0.956549;,
+        -0.084638; 0.279015;-0.956549;,
+        -0.084638; 0.279015;-0.956549;,
+        -0.084638; 0.279015;-0.956549;,
+        -0.028589; 0.094246;-0.995138;,
+        -0.028589; 0.094246;-0.995138;,
+        -0.028589; 0.094246;-0.995138;,
+        -0.046426; 0.086857;-0.995138;,
+        -0.046426; 0.086857;-0.995138;,
+        -0.046426; 0.086857;-0.995138;,
+        -0.137445; 0.257142;-0.956549;,
+        -0.137445; 0.257142;-0.956549;,
+        -0.137445; 0.257142;-0.956549;,
+        -0.137445; 0.257142;-0.956549;,
+        -0.223050; 0.417297;-0.880972;,
+        -0.223050; 0.417297;-0.880972;,
+        -0.223050; 0.417297;-0.880972;,
+        -0.223050; 0.417297;-0.880972;,
+        -0.299913; 0.561098;-0.771506;,
+        -0.299913; 0.561098;-0.771506;,
+        -0.299913; 0.561098;-0.771506;,
+        -0.299913; 0.561098;-0.771506;,
+        -0.365101; 0.683057;-0.632562;,
+        -0.365101; 0.683057;-0.632562;,
+        -0.365101; 0.683057;-0.632562;,
+        -0.365101; 0.683057;-0.632562;,
+        -0.416180; 0.778617;-0.469628;,
+        -0.416180; 0.778617;-0.469628;,
+        -0.416180; 0.778617;-0.469628;,
+        -0.416180; 0.778617;-0.469628;,
+        -0.451281; 0.844288;-0.289004;,
+        -0.451281; 0.844288;-0.289004;,
+        -0.451281; 0.844288;-0.289004;,
+        -0.451281; 0.844288;-0.289004;,
+        -0.469149; 0.877715;-0.097549;,
+        -0.469149; 0.877715;-0.097549;,
+        -0.469149; 0.877715;-0.097549;,
+        -0.469149; 0.877715;-0.097549;,
+        -0.469149; 0.877715; 0.097549;,
+        -0.469149; 0.877715; 0.097549;,
+        -0.469149; 0.877715; 0.097549;,
+        -0.469149; 0.877715; 0.097549;,
+        -0.451281; 0.844288; 0.289004;,
+        -0.451281; 0.844288; 0.289004;,
+        -0.451281; 0.844288; 0.289004;,
+        -0.451281; 0.844288; 0.289004;,
+        -0.416179; 0.778617; 0.469629;,
+        -0.416179; 0.778617; 0.469629;,
+        -0.416179; 0.778617; 0.469629;,
+        -0.416179; 0.778617; 0.469629;,
+        -0.365101; 0.683056; 0.632562;,
+        -0.365101; 0.683056; 0.632562;,
+        -0.365101; 0.683056; 0.632562;,
+        -0.365101; 0.683056; 0.632562;,
+        -0.299913; 0.561098; 0.771506;,
+        -0.299913; 0.561098; 0.771506;,
+        -0.299913; 0.561098; 0.771506;,
+        -0.299913; 0.561098; 0.771506;,
+        -0.223050; 0.417297; 0.880972;,
+        -0.223050; 0.417297; 0.880972;,
+        -0.223050; 0.417297; 0.880972;,
+        -0.223050; 0.417297; 0.880972;,
+        -0.137445; 0.257142; 0.956549;,
+        -0.137445; 0.257142; 0.956549;,
+        -0.137445; 0.257142; 0.956549;,
+        -0.137445; 0.257142; 0.956549;,
+        -0.046426; 0.086858; 0.995138;,
+        -0.046426; 0.086858; 0.995138;,
+        -0.046426; 0.086858; 0.995138;,
+        -0.062480; 0.076131; 0.995138;,
+        -0.062480; 0.076131; 0.995138;,
+        -0.062480; 0.076131; 0.995138;,
+        -0.184970; 0.225387; 0.956549;,
+        -0.184970; 0.225387; 0.956549;,
+        -0.184970; 0.225387; 0.956549;,
+        -0.184970; 0.225387; 0.956549;,
+        -0.300175; 0.365764; 0.880972;,
+        -0.300175; 0.365764; 0.880972;,
+        -0.300175; 0.365764; 0.880972;,
+        -0.300175; 0.365764; 0.880972;,
+        -0.403615; 0.491806; 0.771506;,
+        -0.403615; 0.491806; 0.771506;,
+        -0.403615; 0.491806; 0.771506;,
+        -0.403615; 0.491806; 0.771506;,
+        -0.491344; 0.598704; 0.632562;,
+        -0.491344; 0.598704; 0.632562;,
+        -0.491344; 0.598704; 0.632562;,
+        -0.491344; 0.598704; 0.632562;,
+        -0.560083; 0.682463; 0.469628;,
+        -0.560083; 0.682463; 0.469628;,
+        -0.560083; 0.682463; 0.469628;,
+        -0.560083; 0.682463; 0.469628;,
+        -0.607323; 0.740025; 0.289004;,
+        -0.607323; 0.740025; 0.289004;,
+        -0.607323; 0.740025; 0.289004;,
+        -0.607323; 0.740025; 0.289004;,
+        -0.631368; 0.769324; 0.097548;,
+        -0.631368; 0.769324; 0.097548;,
+        -0.631368; 0.769324; 0.097548;,
+        -0.631368; 0.769324; 0.097548;,
+        -0.631368; 0.769324;-0.097548;,
+        -0.631368; 0.769324;-0.097548;,
+        -0.631368; 0.769324;-0.097548;,
+        -0.631368; 0.769324;-0.097548;,
+        -0.607322; 0.740025;-0.289004;,
+        -0.607322; 0.740025;-0.289004;,
+        -0.607322; 0.740025;-0.289004;,
+        -0.607322; 0.740025;-0.289004;,
+        -0.560083; 0.682463;-0.469628;,
+        -0.560083; 0.682463;-0.469628;,
+        -0.560083; 0.682463;-0.469628;,
+        -0.560083; 0.682463;-0.469628;,
+        -0.491344; 0.598704;-0.632562;,
+        -0.491344; 0.598704;-0.632562;,
+        -0.491344; 0.598704;-0.632562;,
+        -0.491344; 0.598704;-0.632562;,
+        -0.403615; 0.491806;-0.771506;,
+        -0.403615; 0.491806;-0.771506;,
+        -0.403615; 0.491806;-0.771506;,
+        -0.403615; 0.491806;-0.771506;,
+        -0.300175; 0.365764;-0.880972;,
+        -0.300175; 0.365764;-0.880972;,
+        -0.300175; 0.365764;-0.880972;,
+        -0.300175; 0.365764;-0.880972;,
+        -0.184970; 0.225387;-0.956549;,
+        -0.184970; 0.225387;-0.956549;,
+        -0.184970; 0.225387;-0.956549;,
+        -0.184970; 0.225387;-0.956549;,
+        -0.062479; 0.076131;-0.995138;,
+        -0.062479; 0.076131;-0.995138;,
+        -0.062479; 0.076131;-0.995138;,
+        -0.076131; 0.062479;-0.995138;,
+        -0.076131; 0.062479;-0.995138;,
+        -0.076131; 0.062479;-0.995138;,
+        -0.225387; 0.184970;-0.956550;,
+        -0.225387; 0.184970;-0.956550;,
+        -0.225387; 0.184970;-0.956550;,
+        -0.225387; 0.184970;-0.956550;,
+        -0.365764; 0.300175;-0.880972;,
+        -0.365764; 0.300175;-0.880972;,
+        -0.365764; 0.300175;-0.880972;,
+        -0.365764; 0.300175;-0.880972;,
+        -0.491806; 0.403615;-0.771506;,
+        -0.491806; 0.403615;-0.771506;,
+        -0.491806; 0.403615;-0.771506;,
+        -0.491806; 0.403615;-0.771506;,
+        -0.598704; 0.491344;-0.632562;,
+        -0.598704; 0.491344;-0.632562;,
+        -0.598704; 0.491344;-0.632562;,
+        -0.598704; 0.491344;-0.632562;,
+        -0.682463; 0.560083;-0.469628;,
+        -0.682463; 0.560083;-0.469628;,
+        -0.682463; 0.560083;-0.469628;,
+        -0.682463; 0.560083;-0.469628;,
+        -0.740025; 0.607322;-0.289004;,
+        -0.740025; 0.607322;-0.289004;,
+        -0.740025; 0.607322;-0.289004;,
+        -0.740025; 0.607322;-0.289004;,
+        -0.769324; 0.631367;-0.097548;,
+        -0.769324; 0.631367;-0.097548;,
+        -0.769324; 0.631367;-0.097548;,
+        -0.769324; 0.631367;-0.097548;,
+        -0.769324; 0.631367; 0.097548;,
+        -0.769324; 0.631367; 0.097548;,
+        -0.769324; 0.631367; 0.097548;,
+        -0.769324; 0.631367; 0.097548;,
+        -0.740025; 0.607322; 0.289004;,
+        -0.740025; 0.607322; 0.289004;,
+        -0.740025; 0.607322; 0.289004;,
+        -0.740025; 0.607322; 0.289004;,
+        -0.682463; 0.560083; 0.469629;,
+        -0.682463; 0.560083; 0.469629;,
+        -0.682463; 0.560083; 0.469629;,
+        -0.682463; 0.560083; 0.469629;,
+        -0.598704; 0.491344; 0.632562;,
+        -0.598704; 0.491344; 0.632562;,
+        -0.598704; 0.491344; 0.632562;,
+        -0.598704; 0.491344; 0.632562;,
+        -0.491806; 0.403615; 0.771506;,
+        -0.491806; 0.403615; 0.771506;,
+        -0.491806; 0.403615; 0.771506;,
+        -0.491806; 0.403615; 0.771506;,
+        -0.365764; 0.300175; 0.880972;,
+        -0.365764; 0.300175; 0.880972;,
+        -0.365764; 0.300175; 0.880972;,
+        -0.365764; 0.300175; 0.880972;,
+        -0.225387; 0.184970; 0.956549;,
+        -0.225387; 0.184970; 0.956549;,
+        -0.225387; 0.184970; 0.956549;,
+        -0.225387; 0.184970; 0.956549;,
+        -0.076132; 0.062479; 0.995138;,
+        -0.076132; 0.062479; 0.995138;,
+        -0.076132; 0.062479; 0.995138;,
+        -0.086858; 0.046426; 0.995138;,
+        -0.086858; 0.046426; 0.995138;,
+        -0.086858; 0.046426; 0.995138;,
+        -0.257142; 0.137445; 0.956549;,
+        -0.257142; 0.137445; 0.956549;,
+        -0.257142; 0.137445; 0.956549;,
+        -0.257142; 0.137445; 0.956549;,
+        -0.417297; 0.223050; 0.880972;,
+        -0.417297; 0.223050; 0.880972;,
+        -0.417297; 0.223050; 0.880972;,
+        -0.417297; 0.223050; 0.880972;,
+        -0.561098; 0.299913; 0.771506;,
+        -0.561098; 0.299913; 0.771506;,
+        -0.561098; 0.299913; 0.771506;,
+        -0.561098; 0.299913; 0.771506;,
+        -0.683057; 0.365101; 0.632562;,
+        -0.683057; 0.365101; 0.632562;,
+        -0.683057; 0.365101; 0.632562;,
+        -0.683057; 0.365101; 0.632562;,
+        -0.778617; 0.416179; 0.469629;,
+        -0.778617; 0.416179; 0.469629;,
+        -0.778617; 0.416179; 0.469629;,
+        -0.778617; 0.416179; 0.469629;,
+        -0.844288; 0.451281; 0.289004;,
+        -0.844288; 0.451281; 0.289004;,
+        -0.844288; 0.451281; 0.289004;,
+        -0.844288; 0.451281; 0.289004;,
+        -0.877715; 0.469148; 0.097549;,
+        -0.877715; 0.469148; 0.097549;,
+        -0.877715; 0.469148; 0.097549;,
+        -0.877715; 0.469148; 0.097549;,
+        -0.877715; 0.469148;-0.097549;,
+        -0.877715; 0.469148;-0.097549;,
+        -0.877715; 0.469148;-0.097549;,
+        -0.877715; 0.469148;-0.097549;,
+        -0.844288; 0.451281;-0.289003;,
+        -0.844288; 0.451281;-0.289003;,
+        -0.844288; 0.451281;-0.289003;,
+        -0.844288; 0.451281;-0.289003;,
+        -0.778617; 0.416179;-0.469629;,
+        -0.778617; 0.416179;-0.469629;,
+        -0.778617; 0.416179;-0.469629;,
+        -0.778617; 0.416179;-0.469629;,
+        -0.683057; 0.365101;-0.632562;,
+        -0.683057; 0.365101;-0.632562;,
+        -0.683057; 0.365101;-0.632562;,
+        -0.683057; 0.365101;-0.632562;,
+        -0.561098; 0.299913;-0.771506;,
+        -0.561098; 0.299913;-0.771506;,
+        -0.561098; 0.299913;-0.771506;,
+        -0.561098; 0.299913;-0.771506;,
+        -0.417297; 0.223050;-0.880972;,
+        -0.417297; 0.223050;-0.880972;,
+        -0.417297; 0.223050;-0.880972;,
+        -0.417297; 0.223050;-0.880972;,
+        -0.257142; 0.137445;-0.956549;,
+        -0.257142; 0.137445;-0.956549;,
+        -0.257142; 0.137445;-0.956549;,
+        -0.257142; 0.137445;-0.956549;,
+        -0.086857; 0.046426;-0.995138;,
+        -0.086857; 0.046426;-0.995138;,
+        -0.086857; 0.046426;-0.995138;,
+        -0.094246; 0.028589;-0.995138;,
+        -0.094246; 0.028589;-0.995138;,
+        -0.094246; 0.028589;-0.995138;,
+        -0.279015; 0.084638;-0.956550;,
+        -0.279015; 0.084638;-0.956550;,
+        -0.279015; 0.084638;-0.956550;,
+        -0.279015; 0.084638;-0.956550;,
+        -0.452794; 0.137353;-0.880972;,
+        -0.452794; 0.137353;-0.880972;,
+        -0.452794; 0.137353;-0.880972;,
+        -0.452794; 0.137353;-0.880972;,
+        -0.608826; 0.184685;-0.771506;,
+        -0.608826; 0.184685;-0.771506;,
+        -0.608826; 0.184685;-0.771506;,
+        -0.608826; 0.184685;-0.771506;,
+        -0.741160; 0.224828;-0.632562;,
+        -0.741160; 0.224828;-0.632562;,
+        -0.741160; 0.224828;-0.632562;,
+        -0.741160; 0.224828;-0.632562;,
+        -0.844848; 0.256282;-0.469629;,
+        -0.844848; 0.256282;-0.469629;,
+        -0.844848; 0.256282;-0.469629;,
+        -0.844848; 0.256282;-0.469629;,
+        -0.916106; 0.277898;-0.289003;,
+        -0.916106; 0.277898;-0.289003;,
+        -0.916106; 0.277898;-0.289003;,
+        -0.916106; 0.277898;-0.289003;,
+        -0.952377; 0.288900;-0.097549;,
+        -0.952377; 0.288900;-0.097549;,
+        -0.952377; 0.288900;-0.097549;,
+        -0.952377; 0.288900;-0.097549;,
+        -0.952377; 0.288900; 0.097549;,
+        -0.952377; 0.288900; 0.097549;,
+        -0.952377; 0.288900; 0.097549;,
+        -0.952377; 0.288900; 0.097549;,
+        -0.916106; 0.277897; 0.289003;,
+        -0.916106; 0.277897; 0.289003;,
+        -0.916106; 0.277897; 0.289003;,
+        -0.916106; 0.277897; 0.289003;,
+        -0.844848; 0.256282; 0.469628;,
+        -0.844848; 0.256282; 0.469628;,
+        -0.844848; 0.256282; 0.469628;,
+        -0.844848; 0.256282; 0.469628;,
+        -0.741160; 0.224828; 0.632562;,
+        -0.741160; 0.224828; 0.632562;,
+        -0.741160; 0.224828; 0.632562;,
+        -0.741160; 0.224828; 0.632562;,
+        -0.608826; 0.184685; 0.771506;,
+        -0.608826; 0.184685; 0.771506;,
+        -0.608826; 0.184685; 0.771506;,
+        -0.608826; 0.184685; 0.771506;,
+        -0.452794; 0.137353; 0.880972;,
+        -0.452794; 0.137353; 0.880972;,
+        -0.452794; 0.137353; 0.880972;,
+        -0.452794; 0.137353; 0.880972;,
+        -0.279015; 0.084638; 0.956549;,
+        -0.279015; 0.084638; 0.956549;,
+        -0.279015; 0.084638; 0.956549;,
+        -0.279015; 0.084638; 0.956549;,
+        -0.094246; 0.028589; 0.995138;,
+        -0.094246; 0.028589; 0.995138;,
+        -0.094246; 0.028589; 0.995138;,
+        -0.098013; 0.009653; 0.995138;,
+        -0.098013; 0.009653; 0.995138;,
+        -0.098013; 0.009653; 0.995138;,
+        -0.290166; 0.028579; 0.956549;,
+        -0.290166; 0.028579; 0.956549;,
+        -0.290166; 0.028579; 0.956549;,
+        -0.290166; 0.028579; 0.956549;,
+        -0.470890; 0.046378; 0.880972;,
+        -0.470890; 0.046378; 0.880972;,
+        -0.470890; 0.046378; 0.880972;,
+        -0.470890; 0.046378; 0.880972;,
+        -0.633158; 0.062360; 0.771506;,
+        -0.633158; 0.062360; 0.771506;,
+        -0.633158; 0.062360; 0.771506;,
+        -0.633158; 0.062360; 0.771506;,
+        -0.770780; 0.075915; 0.632562;,
+        -0.770780; 0.075915; 0.632562;,
+        -0.770780; 0.075915; 0.632562;,
+        -0.770780; 0.075915; 0.632562;,
+        -0.878613; 0.086536; 0.469628;,
+        -0.878613; 0.086536; 0.469628;,
+        -0.878613; 0.086536; 0.469628;,
+        -0.878613; 0.086536; 0.469628;,
+        -0.952718; 0.093834; 0.289004;,
+        -0.952718; 0.093834; 0.289004;,
+        -0.952718; 0.093834; 0.289004;,
+        -0.952718; 0.093834; 0.289004;,
+        -0.990439; 0.097549; 0.097548;,
+        -0.990439; 0.097549; 0.097548;,
+        -0.990439; 0.097549; 0.097548;,
+        -0.990439; 0.097549; 0.097548;,
+        -0.990439; 0.097549;-0.097548;,
+        -0.990439; 0.097549;-0.097548;,
+        -0.990439; 0.097549;-0.097548;,
+        -0.990439; 0.097549;-0.097548;,
+        -0.952718; 0.093834;-0.289003;,
+        -0.952718; 0.093834;-0.289003;,
+        -0.952718; 0.093834;-0.289003;,
+        -0.952718; 0.093834;-0.289003;,
+        -0.878613; 0.086536;-0.469629;,
+        -0.878613; 0.086536;-0.469629;,
+        -0.878613; 0.086536;-0.469629;,
+        -0.878613; 0.086536;-0.469629;,
+        -0.770780; 0.075915;-0.632562;,
+        -0.770780; 0.075915;-0.632562;,
+        -0.770780; 0.075915;-0.632562;,
+        -0.770780; 0.075915;-0.632562;,
+        -0.633158; 0.062360;-0.771506;,
+        -0.633158; 0.062360;-0.771506;,
+        -0.633158; 0.062360;-0.771506;,
+        -0.633158; 0.062360;-0.771506;,
+        -0.470890; 0.046378;-0.880972;,
+        -0.470890; 0.046378;-0.880972;,
+        -0.470890; 0.046378;-0.880972;,
+        -0.470890; 0.046378;-0.880972;,
+        -0.290166; 0.028579;-0.956549;,
+        -0.290166; 0.028579;-0.956549;,
+        -0.290166; 0.028579;-0.956549;,
+        -0.290166; 0.028579;-0.956549;,
+        -0.098012; 0.009653;-0.995138;,
+        -0.098012; 0.009653;-0.995138;,
+        -0.098012; 0.009653;-0.995138;,
+        -0.098012;-0.009653;-0.995138;,
+        -0.098012;-0.009653;-0.995138;,
+        -0.098012;-0.009653;-0.995138;,
+        -0.290166;-0.028579;-0.956549;,
+        -0.290166;-0.028579;-0.956549;,
+        -0.290166;-0.028579;-0.956549;,
+        -0.290166;-0.028579;-0.956549;,
+        -0.470890;-0.046379;-0.880972;,
+        -0.470890;-0.046379;-0.880972;,
+        -0.470890;-0.046379;-0.880972;,
+        -0.470890;-0.046379;-0.880972;,
+        -0.633158;-0.062361;-0.771506;,
+        -0.633158;-0.062361;-0.771506;,
+        -0.633158;-0.062361;-0.771506;,
+        -0.633158;-0.062361;-0.771506;,
+        -0.770780;-0.075915;-0.632562;,
+        -0.770780;-0.075915;-0.632562;,
+        -0.770780;-0.075915;-0.632562;,
+        -0.770780;-0.075915;-0.632562;,
+        -0.878613;-0.086536;-0.469629;,
+        -0.878613;-0.086536;-0.469629;,
+        -0.878613;-0.086536;-0.469629;,
+        -0.878613;-0.086536;-0.469629;,
+        -0.952718;-0.093835;-0.289003;,
+        -0.952718;-0.093835;-0.289003;,
+        -0.952718;-0.093835;-0.289003;,
+        -0.952718;-0.093835;-0.289003;,
+        -0.990438;-0.097550;-0.097548;,
+        -0.990438;-0.097550;-0.097548;,
+        -0.990438;-0.097550;-0.097548;,
+        -0.990438;-0.097550;-0.097548;,
+        -0.990438;-0.097550; 0.097548;,
+        -0.990438;-0.097550; 0.097548;,
+        -0.990438;-0.097550; 0.097548;,
+        -0.990438;-0.097550; 0.097548;,
+        -0.952718;-0.093835; 0.289004;,
+        -0.952718;-0.093835; 0.289004;,
+        -0.952718;-0.093835; 0.289004;,
+        -0.952718;-0.093835; 0.289004;,
+        -0.878613;-0.086536; 0.469628;,
+        -0.878613;-0.086536; 0.469628;,
+        -0.878613;-0.086536; 0.469628;,
+        -0.878613;-0.086536; 0.469628;,
+        -0.770780;-0.075915; 0.632562;,
+        -0.770780;-0.075915; 0.632562;,
+        -0.770780;-0.075915; 0.632562;,
+        -0.770780;-0.075915; 0.632562;,
+        -0.633158;-0.062361; 0.771506;,
+        -0.633158;-0.062361; 0.771506;,
+        -0.633158;-0.062361; 0.771506;,
+        -0.633158;-0.062361; 0.771506;,
+        -0.470890;-0.046379; 0.880972;,
+        -0.470890;-0.046379; 0.880972;,
+        -0.470890;-0.046379; 0.880972;,
+        -0.470890;-0.046379; 0.880972;,
+        -0.290166;-0.028579; 0.956549;,
+        -0.290166;-0.028579; 0.956549;,
+        -0.290166;-0.028579; 0.956549;,
+        -0.290166;-0.028579; 0.956549;,
+        -0.098013;-0.009653; 0.995138;,
+        -0.098013;-0.009653; 0.995138;,
+        -0.098013;-0.009653; 0.995138;,
+        -0.094246;-0.028589; 0.995138;,
+        -0.094246;-0.028589; 0.995138;,
+        -0.094246;-0.028589; 0.995138;,
+        -0.279015;-0.084638; 0.956549;,
+        -0.279015;-0.084638; 0.956549;,
+        -0.279015;-0.084638; 0.956549;,
+        -0.279015;-0.084638; 0.956549;,
+        -0.452794;-0.137354; 0.880972;,
+        -0.452794;-0.137354; 0.880972;,
+        -0.452794;-0.137354; 0.880972;,
+        -0.452794;-0.137354; 0.880972;,
+        -0.608826;-0.184686; 0.771506;,
+        -0.608826;-0.184686; 0.771506;,
+        -0.608826;-0.184686; 0.771506;,
+        -0.608826;-0.184686; 0.771506;,
+        -0.741159;-0.224828; 0.632562;,
+        -0.741159;-0.224828; 0.632562;,
+        -0.741159;-0.224828; 0.632562;,
+        -0.741159;-0.224828; 0.632562;,
+        -0.844848;-0.256282; 0.469628;,
+        -0.844848;-0.256282; 0.469628;,
+        -0.844848;-0.256282; 0.469628;,
+        -0.844848;-0.256282; 0.469628;,
+        -0.916106;-0.277898; 0.289004;,
+        -0.916106;-0.277898; 0.289004;,
+        -0.916106;-0.277898; 0.289004;,
+        -0.916106;-0.277898; 0.289004;,
+        -0.952376;-0.288901; 0.097548;,
+        -0.952376;-0.288901; 0.097548;,
+        -0.952376;-0.288901; 0.097548;,
+        -0.952376;-0.288901; 0.097548;,
+        -0.952376;-0.288901;-0.097548;,
+        -0.952376;-0.288901;-0.097548;,
+        -0.952376;-0.288901;-0.097548;,
+        -0.952376;-0.288901;-0.097548;,
+        -0.916106;-0.277898;-0.289003;,
+        -0.916106;-0.277898;-0.289003;,
+        -0.916106;-0.277898;-0.289003;,
+        -0.916106;-0.277898;-0.289003;,
+        -0.844848;-0.256282;-0.469629;,
+        -0.844848;-0.256282;-0.469629;,
+        -0.844848;-0.256282;-0.469629;,
+        -0.844848;-0.256282;-0.469629;,
+        -0.741160;-0.224828;-0.632562;,
+        -0.741160;-0.224828;-0.632562;,
+        -0.741160;-0.224828;-0.632562;,
+        -0.741160;-0.224828;-0.632562;,
+        -0.608826;-0.184686;-0.771506;,
+        -0.608826;-0.184686;-0.771506;,
+        -0.608826;-0.184686;-0.771506;,
+        -0.608826;-0.184686;-0.771506;,
+        -0.452794;-0.137354;-0.880972;,
+        -0.452794;-0.137354;-0.880972;,
+        -0.452794;-0.137354;-0.880972;,
+        -0.452794;-0.137354;-0.880972;,
+        -0.279015;-0.084638;-0.956549;,
+        -0.279015;-0.084638;-0.956549;,
+        -0.279015;-0.084638;-0.956549;,
+        -0.279015;-0.084638;-0.956549;,
+        -0.094246;-0.028589;-0.995138;,
+        -0.094246;-0.028589;-0.995138;,
+        -0.094246;-0.028589;-0.995138;,
+        -0.086857;-0.046426;-0.995138;,
+        -0.086857;-0.046426;-0.995138;,
+        -0.086857;-0.046426;-0.995138;,
+        -0.257142;-0.137445;-0.956549;,
+        -0.257142;-0.137445;-0.956549;,
+        -0.257142;-0.137445;-0.956549;,
+        -0.257142;-0.137445;-0.956549;,
+        -0.417297;-0.223050;-0.880972;,
+        -0.417297;-0.223050;-0.880972;,
+        -0.417297;-0.223050;-0.880972;,
+        -0.417297;-0.223050;-0.880972;,
+        -0.561098;-0.299913;-0.771506;,
+        -0.561098;-0.299913;-0.771506;,
+        -0.561098;-0.299913;-0.771506;,
+        -0.561098;-0.299913;-0.771506;,
+        -0.683057;-0.365102;-0.632562;,
+        -0.683057;-0.365102;-0.632562;,
+        -0.683057;-0.365102;-0.632562;,
+        -0.683057;-0.365102;-0.632562;,
+        -0.778616;-0.416179;-0.469629;,
+        -0.778616;-0.416179;-0.469629;,
+        -0.778616;-0.416179;-0.469629;,
+        -0.778616;-0.416179;-0.469629;,
+        -0.844288;-0.451281;-0.289003;,
+        -0.844288;-0.451281;-0.289003;,
+        -0.844288;-0.451281;-0.289003;,
+        -0.844288;-0.451281;-0.289003;,
+        -0.877715;-0.469149;-0.097548;,
+        -0.877715;-0.469149;-0.097548;,
+        -0.877715;-0.469149;-0.097548;,
+        -0.877715;-0.469149;-0.097548;,
+        -0.877715;-0.469149; 0.097548;,
+        -0.877715;-0.469149; 0.097548;,
+        -0.877715;-0.469149; 0.097548;,
+        -0.877715;-0.469149; 0.097548;,
+        -0.844288;-0.451281; 0.289004;,
+        -0.844288;-0.451281; 0.289004;,
+        -0.844288;-0.451281; 0.289004;,
+        -0.844288;-0.451281; 0.289004;,
+        -0.778617;-0.416179; 0.469628;,
+        -0.778617;-0.416179; 0.469628;,
+        -0.778617;-0.416179; 0.469628;,
+        -0.778617;-0.416179; 0.469628;,
+        -0.683057;-0.365101; 0.632562;,
+        -0.683057;-0.365101; 0.632562;,
+        -0.683057;-0.365101; 0.632562;,
+        -0.683057;-0.365101; 0.632562;,
+        -0.561097;-0.299913; 0.771506;,
+        -0.561097;-0.299913; 0.771506;,
+        -0.561097;-0.299913; 0.771506;,
+        -0.561097;-0.299913; 0.771506;,
+        -0.417297;-0.223050; 0.880972;,
+        -0.417297;-0.223050; 0.880972;,
+        -0.417297;-0.223050; 0.880972;,
+        -0.417297;-0.223050; 0.880972;,
+        -0.257142;-0.137445; 0.956549;,
+        -0.257142;-0.137445; 0.956549;,
+        -0.257142;-0.137445; 0.956549;,
+        -0.257142;-0.137445; 0.956549;,
+        -0.086858;-0.046426; 0.995138;,
+        -0.086858;-0.046426; 0.995138;,
+        -0.086858;-0.046426; 0.995138;,
+        -0.076131;-0.062480; 0.995138;,
+        -0.076131;-0.062480; 0.995138;,
+        -0.076131;-0.062480; 0.995138;,
+        -0.225387;-0.184970; 0.956549;,
+        -0.225387;-0.184970; 0.956549;,
+        -0.225387;-0.184970; 0.956549;,
+        -0.225387;-0.184970; 0.956549;,
+        -0.365764;-0.300175; 0.880972;,
+        -0.365764;-0.300175; 0.880972;,
+        -0.365764;-0.300175; 0.880972;,
+        -0.365764;-0.300175; 0.880972;,
+        -0.491806;-0.403615; 0.771506;,
+        -0.491806;-0.403615; 0.771506;,
+        -0.491806;-0.403615; 0.771506;,
+        -0.491806;-0.403615; 0.771506;,
+        -0.598704;-0.491344; 0.632562;,
+        -0.598704;-0.491344; 0.632562;,
+        -0.598704;-0.491344; 0.632562;,
+        -0.598704;-0.491344; 0.632562;,
+        -0.682463;-0.560083; 0.469628;,
+        -0.682463;-0.560083; 0.469628;,
+        -0.682463;-0.560083; 0.469628;,
+        -0.682463;-0.560083; 0.469628;,
+        -0.740024;-0.607323; 0.289004;,
+        -0.740024;-0.607323; 0.289004;,
+        -0.740024;-0.607323; 0.289004;,
+        -0.740024;-0.607323; 0.289004;,
+        -0.769324;-0.631368; 0.097548;,
+        -0.769324;-0.631368; 0.097548;,
+        -0.769324;-0.631368; 0.097548;,
+        -0.769324;-0.631368; 0.097548;,
+        -0.769324;-0.631368;-0.097548;,
+        -0.769324;-0.631368;-0.097548;,
+        -0.769324;-0.631368;-0.097548;,
+        -0.769324;-0.631368;-0.097548;,
+        -0.740025;-0.607323;-0.289003;,
+        -0.740025;-0.607323;-0.289003;,
+        -0.740025;-0.607323;-0.289003;,
+        -0.740025;-0.607323;-0.289003;,
+        -0.682463;-0.560083;-0.469629;,
+        -0.682463;-0.560083;-0.469629;,
+        -0.682463;-0.560083;-0.469629;,
+        -0.682463;-0.560083;-0.469629;,
+        -0.598704;-0.491344;-0.632562;,
+        -0.598704;-0.491344;-0.632562;,
+        -0.598704;-0.491344;-0.632562;,
+        -0.598704;-0.491344;-0.632562;,
+        -0.491806;-0.403615;-0.771506;,
+        -0.491806;-0.403615;-0.771506;,
+        -0.491806;-0.403615;-0.771506;,
+        -0.491806;-0.403615;-0.771506;,
+        -0.365764;-0.300175;-0.880972;,
+        -0.365764;-0.300175;-0.880972;,
+        -0.365764;-0.300175;-0.880972;,
+        -0.365764;-0.300175;-0.880972;,
+        -0.225387;-0.184970;-0.956549;,
+        -0.225387;-0.184970;-0.956549;,
+        -0.225387;-0.184970;-0.956549;,
+        -0.225387;-0.184970;-0.956549;,
+        -0.076131;-0.062479;-0.995138;,
+        -0.076131;-0.062479;-0.995138;,
+        -0.076131;-0.062479;-0.995138;,
+        -0.062479;-0.076131;-0.995138;,
+        -0.062479;-0.076131;-0.995138;,
+        -0.062479;-0.076131;-0.995138;,
+        -0.184970;-0.225387;-0.956549;,
+        -0.184970;-0.225387;-0.956549;,
+        -0.184970;-0.225387;-0.956549;,
+        -0.184970;-0.225387;-0.956549;,
+        -0.300175;-0.365764;-0.880972;,
+        -0.300175;-0.365764;-0.880972;,
+        -0.300175;-0.365764;-0.880972;,
+        -0.300175;-0.365764;-0.880972;,
+        -0.403615;-0.491806;-0.771506;,
+        -0.403615;-0.491806;-0.771506;,
+        -0.403615;-0.491806;-0.771506;,
+        -0.403615;-0.491806;-0.771506;,
+        -0.491344;-0.598705;-0.632562;,
+        -0.491344;-0.598705;-0.632562;,
+        -0.491344;-0.598705;-0.632562;,
+        -0.491344;-0.598705;-0.632562;,
+        -0.560083;-0.682463;-0.469629;,
+        -0.560083;-0.682463;-0.469629;,
+        -0.560083;-0.682463;-0.469629;,
+        -0.560083;-0.682463;-0.469629;,
+        -0.607322;-0.740025;-0.289003;,
+        -0.607322;-0.740025;-0.289003;,
+        -0.607322;-0.740025;-0.289003;,
+        -0.607322;-0.740025;-0.289003;,
+        -0.631367;-0.769324;-0.097547;,
+        -0.631367;-0.769324;-0.097547;,
+        -0.631367;-0.769324;-0.097547;,
+        -0.631367;-0.769324;-0.097547;,
+        -0.631367;-0.769324; 0.097547;,
+        -0.631367;-0.769324; 0.097547;,
+        -0.631367;-0.769324; 0.097547;,
+        -0.631367;-0.769324; 0.097547;,
+        -0.607322;-0.740025; 0.289004;,
+        -0.607322;-0.740025; 0.289004;,
+        -0.607322;-0.740025; 0.289004;,
+        -0.607322;-0.740025; 0.289004;,
+        -0.560083;-0.682463; 0.469629;,
+        -0.560083;-0.682463; 0.469629;,
+        -0.560083;-0.682463; 0.469629;,
+        -0.560083;-0.682463; 0.469629;,
+        -0.491344;-0.598704; 0.632562;,
+        -0.491344;-0.598704; 0.632562;,
+        -0.491344;-0.598704; 0.632562;,
+        -0.491344;-0.598704; 0.632562;,
+        -0.403614;-0.491806; 0.771506;,
+        -0.403614;-0.491806; 0.771506;,
+        -0.403614;-0.491806; 0.771506;,
+        -0.403614;-0.491806; 0.771506;,
+        -0.300175;-0.365764; 0.880972;,
+        -0.300175;-0.365764; 0.880972;,
+        -0.300175;-0.365764; 0.880972;,
+        -0.300175;-0.365764; 0.880972;,
+        -0.184970;-0.225387; 0.956549;,
+        -0.184970;-0.225387; 0.956549;,
+        -0.184970;-0.225387; 0.956549;,
+        -0.184970;-0.225387; 0.956549;,
+        -0.062480;-0.076132; 0.995138;,
+        -0.062480;-0.076132; 0.995138;,
+        -0.062480;-0.076132; 0.995138;,
+        -0.046426;-0.086858; 0.995138;,
+        -0.046426;-0.086858; 0.995138;,
+        -0.046426;-0.086858; 0.995138;,
+        -0.137445;-0.257142; 0.956549;,
+        -0.137445;-0.257142; 0.956549;,
+        -0.137445;-0.257142; 0.956549;,
+        -0.137445;-0.257142; 0.956549;,
+        -0.223050;-0.417297; 0.880972;,
+        -0.223050;-0.417297; 0.880972;,
+        -0.223050;-0.417297; 0.880972;,
+        -0.223050;-0.417297; 0.880972;,
+        -0.299913;-0.561097; 0.771506;,
+        -0.299913;-0.561097; 0.771506;,
+        -0.299913;-0.561097; 0.771506;,
+        -0.299913;-0.561097; 0.771506;,
+        -0.365101;-0.683057; 0.632562;,
+        -0.365101;-0.683057; 0.632562;,
+        -0.365101;-0.683057; 0.632562;,
+        -0.365101;-0.683057; 0.632562;,
+        -0.416179;-0.778617; 0.469629;,
+        -0.416179;-0.778617; 0.469629;,
+        -0.416179;-0.778617; 0.469629;,
+        -0.416179;-0.778617; 0.469629;,
+        -0.451281;-0.844288; 0.289004;,
+        -0.451281;-0.844288; 0.289004;,
+        -0.451281;-0.844288; 0.289004;,
+        -0.451281;-0.844288; 0.289004;,
+        -0.469148;-0.877715; 0.097547;,
+        -0.469148;-0.877715; 0.097547;,
+        -0.469148;-0.877715; 0.097547;,
+        -0.469148;-0.877715; 0.097547;,
+        -0.469148;-0.877715;-0.097547;,
+        -0.469148;-0.877715;-0.097547;,
+        -0.469148;-0.877715;-0.097547;,
+        -0.469148;-0.877715;-0.097547;,
+        -0.451281;-0.844288;-0.289003;,
+        -0.451281;-0.844288;-0.289003;,
+        -0.451281;-0.844288;-0.289003;,
+        -0.451281;-0.844288;-0.289003;,
+        -0.416179;-0.778616;-0.469629;,
+        -0.416179;-0.778616;-0.469629;,
+        -0.416179;-0.778616;-0.469629;,
+        -0.416179;-0.778616;-0.469629;,
+        -0.365101;-0.683057;-0.632562;,
+        -0.365101;-0.683057;-0.632562;,
+        -0.365101;-0.683057;-0.632562;,
+        -0.365101;-0.683057;-0.632562;,
+        -0.299913;-0.561098;-0.771506;,
+        -0.299913;-0.561098;-0.771506;,
+        -0.299913;-0.561098;-0.771506;,
+        -0.299913;-0.561098;-0.771506;,
+        -0.223050;-0.417297;-0.880972;,
+        -0.223050;-0.417297;-0.880972;,
+        -0.223050;-0.417297;-0.880972;,
+        -0.223050;-0.417297;-0.880972;,
+        -0.137445;-0.257142;-0.956549;,
+        -0.137445;-0.257142;-0.956549;,
+        -0.137445;-0.257142;-0.956549;,
+        -0.137445;-0.257142;-0.956549;,
+        -0.046426;-0.086857;-0.995138;,
+        -0.046426;-0.086857;-0.995138;,
+        -0.046426;-0.086857;-0.995138;,
+        -0.028589;-0.094246;-0.995138;,
+        -0.028589;-0.094246;-0.995138;,
+        -0.028589;-0.094246;-0.995138;,
+        -0.084638;-0.279015;-0.956549;,
+        -0.084638;-0.279015;-0.956549;,
+        -0.084638;-0.279015;-0.956549;,
+        -0.084638;-0.279015;-0.956549;,
+        -0.137353;-0.452794;-0.880972;,
+        -0.137353;-0.452794;-0.880972;,
+        -0.137353;-0.452794;-0.880972;,
+        -0.137353;-0.452794;-0.880972;,
+        -0.184685;-0.608826;-0.771506;,
+        -0.184685;-0.608826;-0.771506;,
+        -0.184685;-0.608826;-0.771506;,
+        -0.184685;-0.608826;-0.771506;,
+        -0.224828;-0.741160;-0.632561;,
+        -0.224828;-0.741160;-0.632561;,
+        -0.224828;-0.741160;-0.632561;,
+        -0.224828;-0.741160;-0.632561;,
+        -0.256282;-0.844848;-0.469629;,
+        -0.256282;-0.844848;-0.469629;,
+        -0.256282;-0.844848;-0.469629;,
+        -0.256282;-0.844848;-0.469629;,
+        -0.277897;-0.916106;-0.289003;,
+        -0.277897;-0.916106;-0.289003;,
+        -0.277897;-0.916106;-0.289003;,
+        -0.277897;-0.916106;-0.289003;,
+        -0.288900;-0.952377;-0.097547;,
+        -0.288900;-0.952377;-0.097547;,
+        -0.288900;-0.952377;-0.097547;,
+        -0.288900;-0.952377;-0.097547;,
+        -0.288900;-0.952377; 0.097547;,
+        -0.288900;-0.952377; 0.097547;,
+        -0.288900;-0.952377; 0.097547;,
+        -0.288900;-0.952377; 0.097547;,
+        -0.277898;-0.916106; 0.289004;,
+        -0.277898;-0.916106; 0.289004;,
+        -0.277898;-0.916106; 0.289004;,
+        -0.277898;-0.916106; 0.289004;,
+        -0.256282;-0.844848; 0.469629;,
+        -0.256282;-0.844848; 0.469629;,
+        -0.256282;-0.844848; 0.469629;,
+        -0.256282;-0.844848; 0.469629;,
+        -0.224828;-0.741160; 0.632562;,
+        -0.224828;-0.741160; 0.632562;,
+        -0.224828;-0.741160; 0.632562;,
+        -0.224828;-0.741160; 0.632562;,
+        -0.184685;-0.608826; 0.771506;,
+        -0.184685;-0.608826; 0.771506;,
+        -0.184685;-0.608826; 0.771506;,
+        -0.184685;-0.608826; 0.771506;,
+        -0.137353;-0.452794; 0.880972;,
+        -0.137353;-0.452794; 0.880972;,
+        -0.137353;-0.452794; 0.880972;,
+        -0.137353;-0.452794; 0.880972;,
+        -0.084638;-0.279015; 0.956549;,
+        -0.084638;-0.279015; 0.956549;,
+        -0.084638;-0.279015; 0.956549;,
+        -0.084638;-0.279015; 0.956549;,
+        -0.028589;-0.094246; 0.995138;,
+        -0.028589;-0.094246; 0.995138;,
+        -0.028589;-0.094246; 0.995138;,
+        -0.009653;-0.098013; 0.995138;,
+        -0.009653;-0.098013; 0.995138;,
+        -0.009653;-0.098013; 0.995138;,
+        -0.028579;-0.290166; 0.956549;,
+        -0.028579;-0.290166; 0.956549;,
+        -0.028579;-0.290166; 0.956549;,
+        -0.028579;-0.290166; 0.956549;,
+        -0.046378;-0.470890; 0.880972;,
+        -0.046378;-0.470890; 0.880972;,
+        -0.046378;-0.470890; 0.880972;,
+        -0.046378;-0.470890; 0.880972;,
+        -0.062360;-0.633158; 0.771506;,
+        -0.062360;-0.633158; 0.771506;,
+        -0.062360;-0.633158; 0.771506;,
+        -0.062360;-0.633158; 0.771506;,
+        -0.075915;-0.770780; 0.632562;,
+        -0.075915;-0.770780; 0.632562;,
+        -0.075915;-0.770780; 0.632562;,
+        -0.075915;-0.770780; 0.632562;,
+        -0.086536;-0.878613; 0.469629;,
+        -0.086536;-0.878613; 0.469629;,
+        -0.086536;-0.878613; 0.469629;,
+        -0.086536;-0.878613; 0.469629;,
+        -0.093834;-0.952718; 0.289004;,
+        -0.093834;-0.952718; 0.289004;,
+        -0.093834;-0.952718; 0.289004;,
+        -0.093834;-0.952718; 0.289004;,
+        -0.097549;-0.990439; 0.097547;,
+        -0.097549;-0.990439; 0.097547;,
+        -0.097549;-0.990439; 0.097547;,
+        -0.097549;-0.990439; 0.097547;,
+        -0.097549;-0.990439;-0.097547;,
+        -0.097549;-0.990439;-0.097547;,
+        -0.097549;-0.990439;-0.097547;,
+        -0.097549;-0.990439;-0.097547;,
+        -0.093834;-0.952718;-0.289003;,
+        -0.093834;-0.952718;-0.289003;,
+        -0.093834;-0.952718;-0.289003;,
+        -0.093834;-0.952718;-0.289003;,
+        -0.086536;-0.878613;-0.469629;,
+        -0.086536;-0.878613;-0.469629;,
+        -0.086536;-0.878613;-0.469629;,
+        -0.086536;-0.878613;-0.469629;,
+        -0.075915;-0.770781;-0.632561;,
+        -0.075915;-0.770781;-0.632561;,
+        -0.075915;-0.770781;-0.632561;,
+        -0.075915;-0.770781;-0.632561;,
+        -0.062360;-0.633158;-0.771506;,
+        -0.062360;-0.633158;-0.771506;,
+        -0.062360;-0.633158;-0.771506;,
+        -0.062360;-0.633158;-0.771506;,
+        -0.046378;-0.470890;-0.880972;,
+        -0.046378;-0.470890;-0.880972;,
+        -0.046378;-0.470890;-0.880972;,
+        -0.046378;-0.470890;-0.880972;,
+        -0.028579;-0.290166;-0.956549;,
+        -0.028579;-0.290166;-0.956549;,
+        -0.028579;-0.290166;-0.956549;,
+        -0.028579;-0.290166;-0.956549;,
+        -0.009653;-0.098012;-0.995138;,
+        -0.009653;-0.098012;-0.995138;,
+        -0.009653;-0.098012;-0.995138;,
+         0.009653;-0.098012;-0.995138;,
+         0.009653;-0.098012;-0.995138;,
+         0.009653;-0.098012;-0.995138;,
+         0.028579;-0.290166;-0.956549;,
+         0.028579;-0.290166;-0.956549;,
+         0.028579;-0.290166;-0.956549;,
+         0.028579;-0.290166;-0.956549;,
+         0.046379;-0.470890;-0.880972;,
+         0.046379;-0.470890;-0.880972;,
+         0.046379;-0.470890;-0.880972;,
+         0.046379;-0.470890;-0.880972;,
+         0.062361;-0.633158;-0.771506;,
+         0.062361;-0.633158;-0.771506;,
+         0.062361;-0.633158;-0.771506;,
+         0.062361;-0.633158;-0.771506;,
+         0.075915;-0.770781;-0.632561;,
+         0.075915;-0.770781;-0.632561;,
+         0.075915;-0.770781;-0.632561;,
+         0.075915;-0.770781;-0.632561;,
+         0.086536;-0.878613;-0.469629;,
+         0.086536;-0.878613;-0.469629;,
+         0.086536;-0.878613;-0.469629;,
+         0.086536;-0.878613;-0.469629;,
+         0.093835;-0.952718;-0.289003;,
+         0.093835;-0.952718;-0.289003;,
+         0.093835;-0.952718;-0.289003;,
+         0.093835;-0.952718;-0.289003;,
+         0.097550;-0.990439;-0.097547;,
+         0.097550;-0.990439;-0.097547;,
+         0.097550;-0.990439;-0.097547;,
+         0.097550;-0.990439;-0.097547;,
+         0.097550;-0.990439; 0.097547;,
+         0.097550;-0.990439; 0.097547;,
+         0.097550;-0.990439; 0.097547;,
+         0.097550;-0.990439; 0.097547;,
+         0.093835;-0.952718; 0.289004;,
+         0.093835;-0.952718; 0.289004;,
+         0.093835;-0.952718; 0.289004;,
+         0.093835;-0.952718; 0.289004;,
+         0.086536;-0.878613; 0.469629;,
+         0.086536;-0.878613; 0.469629;,
+         0.086536;-0.878613; 0.469629;,
+         0.086536;-0.878613; 0.469629;,
+         0.075915;-0.770780; 0.632562;,
+         0.075915;-0.770780; 0.632562;,
+         0.075915;-0.770780; 0.632562;,
+         0.075915;-0.770780; 0.632562;,
+         0.062361;-0.633158; 0.771506;,
+         0.062361;-0.633158; 0.771506;,
+         0.062361;-0.633158; 0.771506;,
+         0.062361;-0.633158; 0.771506;,
+         0.046379;-0.470890; 0.880972;,
+         0.046379;-0.470890; 0.880972;,
+         0.046379;-0.470890; 0.880972;,
+         0.046379;-0.470890; 0.880972;,
+         0.028579;-0.290166; 0.956549;,
+         0.028579;-0.290166; 0.956549;,
+         0.028579;-0.290166; 0.956549;,
+         0.028579;-0.290166; 0.956549;,
+         0.009653;-0.098013; 0.995138;,
+         0.009653;-0.098013; 0.995138;,
+         0.009653;-0.098013; 0.995138;,
+         0.028589;-0.094246; 0.995138;,
+         0.028589;-0.094246; 0.995138;,
+         0.028589;-0.094246; 0.995138;,
+         0.084638;-0.279015; 0.956549;,
+         0.084638;-0.279015; 0.956549;,
+         0.084638;-0.279015; 0.956549;,
+         0.084638;-0.279015; 0.956549;,
+         0.137354;-0.452794; 0.880972;,
+         0.137354;-0.452794; 0.880972;,
+         0.137354;-0.452794; 0.880972;,
+         0.137354;-0.452794; 0.880972;,
+         0.184686;-0.608826; 0.771506;,
+         0.184686;-0.608826; 0.771506;,
+         0.184686;-0.608826; 0.771506;,
+         0.184686;-0.608826; 0.771506;,
+         0.224829;-0.741160; 0.632562;,
+         0.224829;-0.741160; 0.632562;,
+         0.224829;-0.741160; 0.632562;,
+         0.224829;-0.741160; 0.632562;,
+         0.256282;-0.844848; 0.469629;,
+         0.256282;-0.844848; 0.469629;,
+         0.256282;-0.844848; 0.469629;,
+         0.256282;-0.844848; 0.469629;,
+         0.277898;-0.916106; 0.289004;,
+         0.277898;-0.916106; 0.289004;,
+         0.277898;-0.916106; 0.289004;,
+         0.277898;-0.916106; 0.289004;,
+         0.288901;-0.952376; 0.097547;,
+         0.288901;-0.952376; 0.097547;,
+         0.288901;-0.952376; 0.097547;,
+         0.288901;-0.952376; 0.097547;,
+         0.288901;-0.952376;-0.097547;,
+         0.288901;-0.952376;-0.097547;,
+         0.288901;-0.952376;-0.097547;,
+         0.288901;-0.952376;-0.097547;,
+         0.277898;-0.916106;-0.289003;,
+         0.277898;-0.916106;-0.289003;,
+         0.277898;-0.916106;-0.289003;,
+         0.277898;-0.916106;-0.289003;,
+         0.256282;-0.844848;-0.469629;,
+         0.256282;-0.844848;-0.469629;,
+         0.256282;-0.844848;-0.469629;,
+         0.256282;-0.844848;-0.469629;,
+         0.224829;-0.741160;-0.632561;,
+         0.224829;-0.741160;-0.632561;,
+         0.224829;-0.741160;-0.632561;,
+         0.224829;-0.741160;-0.632561;,
+         0.184686;-0.608826;-0.771506;,
+         0.184686;-0.608826;-0.771506;,
+         0.184686;-0.608826;-0.771506;,
+         0.184686;-0.608826;-0.771506;,
+         0.137354;-0.452794;-0.880972;,
+         0.137354;-0.452794;-0.880972;,
+         0.137354;-0.452794;-0.880972;,
+         0.137354;-0.452794;-0.880972;,
+         0.084638;-0.279015;-0.956549;,
+         0.084638;-0.279015;-0.956549;,
+         0.084638;-0.279015;-0.956549;,
+         0.084638;-0.279015;-0.956549;,
+         0.028589;-0.094246;-0.995138;,
+         0.028589;-0.094246;-0.995138;,
+         0.028589;-0.094246;-0.995138;,
+         0.046426;-0.086857;-0.995138;,
+         0.046426;-0.086857;-0.995138;,
+         0.046426;-0.086857;-0.995138;,
+         0.137445;-0.257142;-0.956549;,
+         0.137445;-0.257142;-0.956549;,
+         0.137445;-0.257142;-0.956549;,
+         0.137445;-0.257142;-0.956549;,
+         0.223050;-0.417297;-0.880972;,
+         0.223050;-0.417297;-0.880972;,
+         0.223050;-0.417297;-0.880972;,
+         0.223050;-0.417297;-0.880972;,
+         0.299913;-0.561097;-0.771506;,
+         0.299913;-0.561097;-0.771506;,
+         0.299913;-0.561097;-0.771506;,
+         0.299913;-0.561097;-0.771506;,
+         0.365102;-0.683057;-0.632561;,
+         0.365102;-0.683057;-0.632561;,
+         0.365102;-0.683057;-0.632561;,
+         0.365102;-0.683057;-0.632561;,
+         0.416179;-0.778616;-0.469629;,
+         0.416179;-0.778616;-0.469629;,
+         0.416179;-0.778616;-0.469629;,
+         0.416179;-0.778616;-0.469629;,
+         0.451282;-0.844288;-0.289003;,
+         0.451282;-0.844288;-0.289003;,
+         0.451282;-0.844288;-0.289003;,
+         0.451282;-0.844288;-0.289003;,
+         0.469149;-0.877715;-0.097547;,
+         0.469149;-0.877715;-0.097547;,
+         0.469149;-0.877715;-0.097547;,
+         0.469149;-0.877715;-0.097547;,
+         0.469149;-0.877715; 0.097547;,
+         0.469149;-0.877715; 0.097547;,
+         0.469149;-0.877715; 0.097547;,
+         0.469149;-0.877715; 0.097547;,
+         0.451281;-0.844288; 0.289004;,
+         0.451281;-0.844288; 0.289004;,
+         0.451281;-0.844288; 0.289004;,
+         0.451281;-0.844288; 0.289004;,
+         0.416179;-0.778617; 0.469629;,
+         0.416179;-0.778617; 0.469629;,
+         0.416179;-0.778617; 0.469629;,
+         0.416179;-0.778617; 0.469629;,
+         0.365102;-0.683057; 0.632562;,
+         0.365102;-0.683057; 0.632562;,
+         0.365102;-0.683057; 0.632562;,
+         0.365102;-0.683057; 0.632562;,
+         0.299913;-0.561097; 0.771507;,
+         0.299913;-0.561097; 0.771507;,
+         0.299913;-0.561097; 0.771507;,
+         0.299913;-0.561097; 0.771507;,
+         0.223050;-0.417297; 0.880972;,
+         0.223050;-0.417297; 0.880972;,
+         0.223050;-0.417297; 0.880972;,
+         0.223050;-0.417297; 0.880972;,
+         0.137445;-0.257142; 0.956549;,
+         0.137445;-0.257142; 0.956549;,
+         0.137445;-0.257142; 0.956549;,
+         0.137445;-0.257142; 0.956549;,
+         0.046426;-0.086858; 0.995138;,
+         0.046426;-0.086858; 0.995138;,
+         0.046426;-0.086858; 0.995138;,
+         0.062480;-0.076132; 0.995138;,
+         0.062480;-0.076132; 0.995138;,
+         0.062480;-0.076132; 0.995138;,
+         0.184970;-0.225387; 0.956549;,
+         0.184970;-0.225387; 0.956549;,
+         0.184970;-0.225387; 0.956549;,
+         0.184970;-0.225387; 0.956549;,
+         0.300175;-0.365764; 0.880972;,
+         0.300175;-0.365764; 0.880972;,
+         0.300175;-0.365764; 0.880972;,
+         0.300175;-0.365764; 0.880972;,
+         0.403615;-0.491806; 0.771507;,
+         0.403615;-0.491806; 0.771507;,
+         0.403615;-0.491806; 0.771507;,
+         0.403615;-0.491806; 0.771507;,
+         0.491344;-0.598704; 0.632562;,
+         0.491344;-0.598704; 0.632562;,
+         0.491344;-0.598704; 0.632562;,
+         0.491344;-0.598704; 0.632562;,
+         0.560083;-0.682463; 0.469629;,
+         0.560083;-0.682463; 0.469629;,
+         0.560083;-0.682463; 0.469629;,
+         0.560083;-0.682463; 0.469629;,
+         0.607323;-0.740024; 0.289004;,
+         0.607323;-0.740024; 0.289004;,
+         0.607323;-0.740024; 0.289004;,
+         0.607323;-0.740024; 0.289004;,
+         0.631368;-0.769324; 0.097547;,
+         0.631368;-0.769324; 0.097547;,
+         0.631368;-0.769324; 0.097547;,
+         0.631368;-0.769324; 0.097547;,
+         0.631368;-0.769324;-0.097547;,
+         0.631368;-0.769324;-0.097547;,
+         0.631368;-0.769324;-0.097547;,
+         0.631368;-0.769324;-0.097547;,
+         0.607323;-0.740025;-0.289003;,
+         0.607323;-0.740025;-0.289003;,
+         0.607323;-0.740025;-0.289003;,
+         0.607323;-0.740025;-0.289003;,
+         0.560083;-0.682463;-0.469629;,
+         0.560083;-0.682463;-0.469629;,
+         0.560083;-0.682463;-0.469629;,
+         0.560083;-0.682463;-0.469629;,
+         0.491344;-0.598704;-0.632561;,
+         0.491344;-0.598704;-0.632561;,
+         0.491344;-0.598704;-0.632561;,
+         0.491344;-0.598704;-0.632561;,
+         0.403615;-0.491806;-0.771506;,
+         0.403615;-0.491806;-0.771506;,
+         0.403615;-0.491806;-0.771506;,
+         0.403615;-0.491806;-0.771506;,
+         0.300175;-0.365764;-0.880972;,
+         0.300175;-0.365764;-0.880972;,
+         0.300175;-0.365764;-0.880972;,
+         0.300175;-0.365764;-0.880972;,
+         0.184970;-0.225387;-0.956549;,
+         0.184970;-0.225387;-0.956549;,
+         0.184970;-0.225387;-0.956549;,
+         0.184970;-0.225387;-0.956549;,
+         0.062479;-0.076131;-0.995138;,
+         0.062479;-0.076131;-0.995138;,
+         0.062479;-0.076131;-0.995138;,
+         0.076131;-0.062479;-0.995138;,
+         0.076131;-0.062479;-0.995138;,
+         0.076131;-0.062479;-0.995138;,
+         0.225387;-0.184970;-0.956549;,
+         0.225387;-0.184970;-0.956549;,
+         0.225387;-0.184970;-0.956549;,
+         0.225387;-0.184970;-0.956549;,
+         0.365764;-0.300175;-0.880972;,
+         0.365764;-0.300175;-0.880972;,
+         0.365764;-0.300175;-0.880972;,
+         0.365764;-0.300175;-0.880972;,
+         0.491806;-0.403615;-0.771506;,
+         0.491806;-0.403615;-0.771506;,
+         0.491806;-0.403615;-0.771506;,
+         0.491806;-0.403615;-0.771506;,
+         0.598705;-0.491344;-0.632561;,
+         0.598705;-0.491344;-0.632561;,
+         0.598705;-0.491344;-0.632561;,
+         0.598705;-0.491344;-0.632561;,
+         0.682463;-0.560083;-0.469629;,
+         0.682463;-0.560083;-0.469629;,
+         0.682463;-0.560083;-0.469629;,
+         0.682463;-0.560083;-0.469629;,
+         0.740025;-0.607322;-0.289003;,
+         0.740025;-0.607322;-0.289003;,
+         0.740025;-0.607322;-0.289003;,
+         0.740025;-0.607322;-0.289003;,
+         0.769324;-0.631367;-0.097547;,
+         0.769324;-0.631367;-0.097547;,
+         0.769324;-0.631367;-0.097547;,
+         0.769324;-0.631367;-0.097547;,
+         0.769324;-0.631367; 0.097547;,
+         0.769324;-0.631367; 0.097547;,
+         0.769324;-0.631367; 0.097547;,
+         0.769324;-0.631367; 0.097547;,
+         0.740025;-0.607322; 0.289004;,
+         0.740025;-0.607322; 0.289004;,
+         0.740025;-0.607322; 0.289004;,
+         0.740025;-0.607322; 0.289004;,
+         0.682463;-0.560083; 0.469629;,
+         0.682463;-0.560083; 0.469629;,
+         0.682463;-0.560083; 0.469629;,
+         0.682463;-0.560083; 0.469629;,
+         0.598704;-0.491344; 0.632562;,
+         0.598704;-0.491344; 0.632562;,
+         0.598704;-0.491344; 0.632562;,
+         0.598704;-0.491344; 0.632562;,
+         0.491806;-0.403614; 0.771507;,
+         0.491806;-0.403614; 0.771507;,
+         0.491806;-0.403614; 0.771507;,
+         0.491806;-0.403614; 0.771507;,
+         0.365764;-0.300175; 0.880972;,
+         0.365764;-0.300175; 0.880972;,
+         0.365764;-0.300175; 0.880972;,
+         0.365764;-0.300175; 0.880972;,
+         0.225387;-0.184970; 0.956549;,
+         0.225387;-0.184970; 0.956549;,
+         0.225387;-0.184970; 0.956549;,
+         0.225387;-0.184970; 0.956549;,
+         0.076132;-0.062480; 0.995138;,
+         0.076132;-0.062480; 0.995138;,
+         0.076132;-0.062480; 0.995138;,
+         0.086858;-0.046426; 0.995138;,
+         0.086858;-0.046426; 0.995138;,
+         0.086858;-0.046426; 0.995138;,
+         0.257142;-0.137445; 0.956549;,
+         0.257142;-0.137445; 0.956549;,
+         0.257142;-0.137445; 0.956549;,
+         0.257142;-0.137445; 0.956549;,
+         0.417298;-0.223050; 0.880972;,
+         0.417298;-0.223050; 0.880972;,
+         0.417298;-0.223050; 0.880972;,
+         0.417298;-0.223050; 0.880972;,
+         0.561097;-0.299912; 0.771507;,
+         0.561097;-0.299912; 0.771507;,
+         0.561097;-0.299912; 0.771507;,
+         0.561097;-0.299912; 0.771507;,
+         0.683057;-0.365101; 0.632562;,
+         0.683057;-0.365101; 0.632562;,
+         0.683057;-0.365101; 0.632562;,
+         0.683057;-0.365101; 0.632562;,
+         0.778617;-0.416179; 0.469629;,
+         0.778617;-0.416179; 0.469629;,
+         0.778617;-0.416179; 0.469629;,
+         0.778617;-0.416179; 0.469629;,
+         0.844288;-0.451281; 0.289003;,
+         0.844288;-0.451281; 0.289003;,
+         0.844288;-0.451281; 0.289003;,
+         0.844288;-0.451281; 0.289003;,
+         0.877716;-0.469148; 0.097547;,
+         0.877716;-0.469148; 0.097547;,
+         0.877716;-0.469148; 0.097547;,
+         0.877716;-0.469148; 0.097547;,
+         0.877716;-0.469148;-0.097547;,
+         0.877716;-0.469148;-0.097547;,
+         0.877716;-0.469148;-0.097547;,
+         0.877716;-0.469148;-0.097547;,
+         0.844288;-0.451281;-0.289003;,
+         0.844288;-0.451281;-0.289003;,
+         0.844288;-0.451281;-0.289003;,
+         0.844288;-0.451281;-0.289003;,
+         0.778617;-0.416179;-0.469629;,
+         0.778617;-0.416179;-0.469629;,
+         0.778617;-0.416179;-0.469629;,
+         0.778617;-0.416179;-0.469629;,
+         0.683057;-0.365101;-0.632561;,
+         0.683057;-0.365101;-0.632561;,
+         0.683057;-0.365101;-0.632561;,
+         0.683057;-0.365101;-0.632561;,
+         0.561097;-0.299913;-0.771506;,
+         0.561097;-0.299913;-0.771506;,
+         0.561097;-0.299913;-0.771506;,
+         0.561097;-0.299913;-0.771506;,
+         0.417297;-0.223050;-0.880972;,
+         0.417297;-0.223050;-0.880972;,
+         0.417297;-0.223050;-0.880972;,
+         0.417297;-0.223050;-0.880972;,
+         0.257142;-0.137445;-0.956550;,
+         0.257142;-0.137445;-0.956550;,
+         0.257142;-0.137445;-0.956550;,
+         0.257142;-0.137445;-0.956550;,
+         0.086857;-0.046426;-0.995138;,
+         0.086857;-0.046426;-0.995138;,
+         0.086857;-0.046426;-0.995138;,
+         0.094246;-0.028589;-0.995138;,
+         0.094246;-0.028589;-0.995138;,
+         0.094246;-0.028589;-0.995138;,
+         0.279015;-0.084638;-0.956549;,
+         0.279015;-0.084638;-0.956549;,
+         0.279015;-0.084638;-0.956549;,
+         0.279015;-0.084638;-0.956549;,
+         0.452794;-0.137353;-0.880972;,
+         0.452794;-0.137353;-0.880972;,
+         0.452794;-0.137353;-0.880972;,
+         0.452794;-0.137353;-0.880972;,
+         0.608826;-0.184685;-0.771506;,
+         0.608826;-0.184685;-0.771506;,
+         0.608826;-0.184685;-0.771506;,
+         0.608826;-0.184685;-0.771506;,
+         0.741160;-0.224828;-0.632561;,
+         0.741160;-0.224828;-0.632561;,
+         0.741160;-0.224828;-0.632561;,
+         0.741160;-0.224828;-0.632561;,
+         0.844848;-0.256282;-0.469629;,
+         0.844848;-0.256282;-0.469629;,
+         0.844848;-0.256282;-0.469629;,
+         0.844848;-0.256282;-0.469629;,
+         0.916106;-0.277897;-0.289003;,
+         0.916106;-0.277897;-0.289003;,
+         0.916106;-0.277897;-0.289003;,
+         0.916106;-0.277897;-0.289003;,
+         0.952377;-0.288900;-0.097547;,
+         0.952377;-0.288900;-0.097547;,
+         0.952377;-0.288900;-0.097547;,
+         0.952377;-0.288900;-0.097547;,
+         0.952377;-0.288900; 0.097547;,
+         0.952377;-0.288900; 0.097547;,
+         0.952377;-0.288900; 0.097547;,
+         0.952377;-0.288900; 0.097547;,
+         0.916106;-0.277897; 0.289003;,
+         0.916106;-0.277897; 0.289003;,
+         0.916106;-0.277897; 0.289003;,
+         0.916106;-0.277897; 0.289003;,
+         0.844848;-0.256282; 0.469629;,
+         0.844848;-0.256282; 0.469629;,
+         0.844848;-0.256282; 0.469629;,
+         0.844848;-0.256282; 0.469629;,
+         0.741160;-0.224828; 0.632562;,
+         0.741160;-0.224828; 0.632562;,
+         0.741160;-0.224828; 0.632562;,
+         0.741160;-0.224828; 0.632562;,
+         0.608826;-0.184685; 0.771507;,
+         0.608826;-0.184685; 0.771507;,
+         0.608826;-0.184685; 0.771507;,
+         0.608826;-0.184685; 0.771507;,
+         0.452794;-0.137353; 0.880972;,
+         0.452794;-0.137353; 0.880972;,
+         0.452794;-0.137353; 0.880972;,
+         0.452794;-0.137353; 0.880972;,
+         0.279015;-0.084638; 0.956549;,
+         0.279015;-0.084638; 0.956549;,
+         0.279015;-0.084638; 0.956549;,
+         0.279015;-0.084638; 0.956549;,
+         0.094246;-0.028589; 0.995138;,
+         0.094246;-0.028589; 0.995138;,
+         0.094246;-0.028589; 0.995138;,
+         0.098013;-0.009653; 0.995138;,
+         0.098013;-0.009653; 0.995138;,
+         0.098013;-0.009653; 0.995138;,
+         0.290166;-0.028579; 0.956549;,
+         0.290166;-0.028579; 0.956549;,
+         0.290166;-0.028579; 0.956549;,
+         0.290166;-0.028579; 0.956549;,
+         0.470890;-0.046378; 0.880972;,
+         0.470890;-0.046378; 0.880972;,
+         0.470890;-0.046378; 0.880972;,
+         0.470890;-0.046378; 0.880972;,
+         0.633157;-0.062360; 0.771507;,
+         0.633157;-0.062360; 0.771507;,
+         0.633157;-0.062360; 0.771507;,
+         0.633157;-0.062360; 0.771507;,
+         0.770781;-0.075915; 0.632562;,
+         0.770781;-0.075915; 0.632562;,
+         0.770781;-0.075915; 0.632562;,
+         0.770781;-0.075915; 0.632562;,
+         0.878613;-0.086536; 0.469628;,
+         0.878613;-0.086536; 0.469628;,
+         0.878613;-0.086536; 0.469628;,
+         0.878613;-0.086536; 0.469628;,
+         0.952718;-0.093834; 0.289003;,
+         0.952718;-0.093834; 0.289003;,
+         0.952718;-0.093834; 0.289003;,
+         0.952718;-0.093834; 0.289003;,
+         0.990439;-0.097549; 0.097547;,
+         0.990439;-0.097549; 0.097547;,
+         0.990439;-0.097549; 0.097547;,
+         0.990439;-0.097549; 0.097547;,
+         0.990439;-0.097549;-0.097547;,
+         0.990439;-0.097549;-0.097547;,
+         0.990439;-0.097549;-0.097547;,
+         0.990439;-0.097549;-0.097547;,
+         0.952718;-0.093834;-0.289003;,
+         0.952718;-0.093834;-0.289003;,
+         0.952718;-0.093834;-0.289003;,
+         0.952718;-0.093834;-0.289003;,
+         0.878613;-0.086536;-0.469629;,
+         0.878613;-0.086536;-0.469629;,
+         0.878613;-0.086536;-0.469629;,
+         0.878613;-0.086536;-0.469629;,
+         0.770781;-0.075915;-0.632561;,
+         0.770781;-0.075915;-0.632561;,
+         0.770781;-0.075915;-0.632561;,
+         0.770781;-0.075915;-0.632561;,
+         0.633158;-0.062360;-0.771506;,
+         0.633158;-0.062360;-0.771506;,
+         0.633158;-0.062360;-0.771506;,
+         0.633158;-0.062360;-0.771506;,
+         0.470890;-0.046378;-0.880972;,
+         0.470890;-0.046378;-0.880972;,
+         0.470890;-0.046378;-0.880972;,
+         0.470890;-0.046378;-0.880972;,
+         0.290166;-0.028579;-0.956549;,
+         0.290166;-0.028579;-0.956549;,
+         0.290166;-0.028579;-0.956549;,
+         0.290166;-0.028579;-0.956549;,
+         0.098012;-0.009653;-0.995138;,
+         0.098012;-0.009653;-0.995138;,
+         0.098012;-0.009653;-0.995138;;
+        512;
+        3;0;1;2;,
+        4;3;4;5;6;,
+        4;7;8;9;10;,
+        4;11;12;13;14;,
+        4;15;16;17;18;,
+        4;19;20;21;22;,
+        4;23;24;25;26;,
+        4;27;28;29;30;,
+        4;31;32;33;34;,
+        4;35;36;37;38;,
+        4;39;40;41;42;,
+        4;43;44;45;46;,
+        4;47;48;49;50;,
+        4;51;52;53;54;,
+        4;55;56;57;58;,
+        3;59;60;61;,
+        3;62;63;64;,
+        4;65;66;67;68;,
+        4;69;70;71;72;,
+        4;73;74;75;76;,
+        4;77;78;79;80;,
+        4;81;82;83;84;,
+        4;85;86;87;88;,
+        4;89;90;91;92;,
+        4;93;94;95;96;,
+        4;97;98;99;100;,
+        4;101;102;103;104;,
+        4;105;106;107;108;,
+        4;109;110;111;112;,
+        4;113;114;115;116;,
+        4;117;118;119;120;,
+        3;121;122;123;,
+        3;124;125;126;,
+        4;127;128;129;130;,
+        4;131;132;133;134;,
+        4;135;136;137;138;,
+        4;139;140;141;142;,
+        4;143;144;145;146;,
+        4;147;148;149;150;,
+        4;151;152;153;154;,
+        4;155;156;157;158;,
+        4;159;160;161;162;,
+        4;163;164;165;166;,
+        4;167;168;169;170;,
+        4;171;172;173;174;,
+        4;175;176;177;178;,
+        4;179;180;181;182;,
+        3;183;184;185;,
+        3;186;187;188;,
+        4;189;190;191;192;,
+        4;193;194;195;196;,
+        4;197;198;199;200;,
+        4;201;202;203;204;,
+        4;205;206;207;208;,
+        4;209;210;211;212;,
+        4;213;214;215;216;,
+        4;217;218;219;220;,
+        4;221;222;223;224;,
+        4;225;226;227;228;,
+        4;229;230;231;232;,
+        4;233;234;235;236;,
+        4;237;238;239;240;,
+        4;241;242;243;244;,
+        3;245;246;247;,
+        3;248;249;250;,
+        4;251;252;253;254;,
+        4;255;256;257;258;,
+        4;259;260;261;262;,
+        4;263;264;265;266;,
+        4;267;268;269;270;,
+        4;271;272;273;274;,
+        4;275;276;277;278;,
+        4;279;280;281;282;,
+        4;283;284;285;286;,
+        4;287;288;289;290;,
+        4;291;292;293;294;,
+        4;295;296;297;298;,
+        4;299;300;301;302;,
+        4;303;304;305;306;,
+        3;307;308;309;,
+        3;310;311;312;,
+        4;313;314;315;316;,
+        4;317;318;319;320;,
+        4;321;322;323;324;,
+        4;325;326;327;328;,
+        4;329;330;331;332;,
+        4;333;334;335;336;,
+        4;337;338;339;340;,
+        4;341;342;343;344;,
+        4;345;346;347;348;,
+        4;349;350;351;352;,
+        4;353;354;355;356;,
+        4;357;358;359;360;,
+        4;361;362;363;364;,
+        4;365;366;367;368;,
+        3;369;370;371;,
+        3;372;373;374;,
+        4;375;376;377;378;,
+        4;379;380;381;382;,
+        4;383;384;385;386;,
+        4;387;388;389;390;,
+        4;391;392;393;394;,
+        4;395;396;397;398;,
+        4;399;400;401;402;,
+        4;403;404;405;406;,
+        4;407;408;409;410;,
+        4;411;412;413;414;,
+        4;415;416;417;418;,
+        4;419;420;421;422;,
+        4;423;424;425;426;,
+        4;427;428;429;430;,
+        3;431;432;433;,
+        3;434;435;436;,
+        4;437;438;439;440;,
+        4;441;442;443;444;,
+        4;445;446;447;448;,
+        4;449;450;451;452;,
+        4;453;454;455;456;,
+        4;457;458;459;460;,
+        4;461;462;463;464;,
+        4;465;466;467;468;,
+        4;469;470;471;472;,
+        4;473;474;475;476;,
+        4;477;478;479;480;,
+        4;481;482;483;484;,
+        4;485;486;487;488;,
+        4;489;490;491;492;,
+        3;493;494;495;,
+        3;496;497;498;,
+        4;499;500;501;502;,
+        4;503;504;505;506;,
+        4;507;508;509;510;,
+        4;511;512;513;514;,
+        4;515;516;517;518;,
+        4;519;520;521;522;,
+        4;523;524;525;526;,
+        4;527;528;529;530;,
+        4;531;532;533;534;,
+        4;535;536;537;538;,
+        4;539;540;541;542;,
+        4;543;544;545;546;,
+        4;547;548;549;550;,
+        4;551;552;553;554;,
+        3;555;556;557;,
+        3;558;559;560;,
+        4;561;562;563;564;,
+        4;565;566;567;568;,
+        4;569;570;571;572;,
+        4;573;574;575;576;,
+        4;577;578;579;580;,
+        4;581;582;583;584;,
+        4;585;586;587;588;,
+        4;589;590;591;592;,
+        4;593;594;595;596;,
+        4;597;598;599;600;,
+        4;601;602;603;604;,
+        4;605;606;607;608;,
+        4;609;610;611;612;,
+        4;613;614;615;616;,
+        3;617;618;619;,
+        3;620;621;622;,
+        4;623;624;625;626;,
+        4;627;628;629;630;,
+        4;631;632;633;634;,
+        4;635;636;637;638;,
+        4;639;640;641;642;,
+        4;643;644;645;646;,
+        4;647;648;649;650;,
+        4;651;652;653;654;,
+        4;655;656;657;658;,
+        4;659;660;661;662;,
+        4;663;664;665;666;,
+        4;667;668;669;670;,
+        4;671;672;673;674;,
+        4;675;676;677;678;,
+        3;679;680;681;,
+        3;682;683;684;,
+        4;685;686;687;688;,
+        4;689;690;691;692;,
+        4;693;694;695;696;,
+        4;697;698;699;700;,
+        4;701;702;703;704;,
+        4;705;706;707;708;,
+        4;709;710;711;712;,
+        4;713;714;715;716;,
+        4;717;718;719;720;,
+        4;721;722;723;724;,
+        4;725;726;727;728;,
+        4;729;730;731;732;,
+        4;733;734;735;736;,
+        4;737;738;739;740;,
+        3;741;742;743;,
+        3;744;745;746;,
+        4;747;748;749;750;,
+        4;751;752;753;754;,
+        4;755;756;757;758;,
+        4;759;760;761;762;,
+        4;763;764;765;766;,
+        4;767;768;769;770;,
+        4;771;772;773;774;,
+        4;775;776;777;778;,
+        4;779;780;781;782;,
+        4;783;784;785;786;,
+        4;787;788;789;790;,
+        4;791;792;793;794;,
+        4;795;796;797;798;,
+        4;799;800;801;802;,
+        3;803;804;805;,
+        3;806;807;808;,
+        4;809;810;811;812;,
+        4;813;814;815;816;,
+        4;817;818;819;820;,
+        4;821;822;823;824;,
+        4;825;826;827;828;,
+        4;829;830;831;832;,
+        4;833;834;835;836;,
+        4;837;838;839;840;,
+        4;841;842;843;844;,
+        4;845;846;847;848;,
+        4;849;850;851;852;,
+        4;853;854;855;856;,
+        4;857;858;859;860;,
+        4;861;862;863;864;,
+        3;865;866;867;,
+        3;868;869;870;,
+        4;871;872;873;874;,
+        4;875;876;877;878;,
+        4;879;880;881;882;,
+        4;883;884;885;886;,
+        4;887;888;889;890;,
+        4;891;892;893;894;,
+        4;895;896;897;898;,
+        4;899;900;901;902;,
+        4;903;904;905;906;,
+        4;907;908;909;910;,
+        4;911;912;913;914;,
+        4;915;916;917;918;,
+        4;919;920;921;922;,
+        4;923;924;925;926;,
+        3;927;928;929;,
+        3;930;931;932;,
+        4;933;934;935;936;,
+        4;937;938;939;940;,
+        4;941;942;943;944;,
+        4;945;946;947;948;,
+        4;949;950;951;952;,
+        4;953;954;955;956;,
+        4;957;958;959;960;,
+        4;961;962;963;964;,
+        4;965;966;967;968;,
+        4;969;970;971;972;,
+        4;973;974;975;976;,
+        4;977;978;979;980;,
+        4;981;982;983;984;,
+        4;985;986;987;988;,
+        3;989;990;991;,
+        3;992;993;994;,
+        4;995;996;997;998;,
+        4;999;1000;1001;1002;,
+        4;1003;1004;1005;1006;,
+        4;1007;1008;1009;1010;,
+        4;1011;1012;1013;1014;,
+        4;1015;1016;1017;1018;,
+        4;1019;1020;1021;1022;,
+        4;1023;1024;1025;1026;,
+        4;1027;1028;1029;1030;,
+        4;1031;1032;1033;1034;,
+        4;1035;1036;1037;1038;,
+        4;1039;1040;1041;1042;,
+        4;1043;1044;1045;1046;,
+        4;1047;1048;1049;1050;,
+        3;1051;1052;1053;,
+        3;1054;1055;1056;,
+        4;1057;1058;1059;1060;,
+        4;1061;1062;1063;1064;,
+        4;1065;1066;1067;1068;,
+        4;1069;1070;1071;1072;,
+        4;1073;1074;1075;1076;,
+        4;1077;1078;1079;1080;,
+        4;1081;1082;1083;1084;,
+        4;1085;1086;1087;1088;,
+        4;1089;1090;1091;1092;,
+        4;1093;1094;1095;1096;,
+        4;1097;1098;1099;1100;,
+        4;1101;1102;1103;1104;,
+        4;1105;1106;1107;1108;,
+        4;1109;1110;1111;1112;,
+        3;1113;1114;1115;,
+        3;1116;1117;1118;,
+        4;1119;1120;1121;1122;,
+        4;1123;1124;1125;1126;,
+        4;1127;1128;1129;1130;,
+        4;1131;1132;1133;1134;,
+        4;1135;1136;1137;1138;,
+        4;1139;1140;1141;1142;,
+        4;1143;1144;1145;1146;,
+        4;1147;1148;1149;1150;,
+        4;1151;1152;1153;1154;,
+        4;1155;1156;1157;1158;,
+        4;1159;1160;1161;1162;,
+        4;1163;1164;1165;1166;,
+        4;1167;1168;1169;1170;,
+        4;1171;1172;1173;1174;,
+        3;1175;1176;1177;,
+        3;1178;1179;1180;,
+        4;1181;1182;1183;1184;,
+        4;1185;1186;1187;1188;,
+        4;1189;1190;1191;1192;,
+        4;1193;1194;1195;1196;,
+        4;1197;1198;1199;1200;,
+        4;1201;1202;1203;1204;,
+        4;1205;1206;1207;1208;,
+        4;1209;1210;1211;1212;,
+        4;1213;1214;1215;1216;,
+        4;1217;1218;1219;1220;,
+        4;1221;1222;1223;1224;,
+        4;1225;1226;1227;1228;,
+        4;1229;1230;1231;1232;,
+        4;1233;1234;1235;1236;,
+        3;1237;1238;1239;,
+        3;1240;1241;1242;,
+        4;1243;1244;1245;1246;,
+        4;1247;1248;1249;1250;,
+        4;1251;1252;1253;1254;,
+        4;1255;1256;1257;1258;,
+        4;1259;1260;1261;1262;,
+        4;1263;1264;1265;1266;,
+        4;1267;1268;1269;1270;,
+        4;1271;1272;1273;1274;,
+        4;1275;1276;1277;1278;,
+        4;1279;1280;1281;1282;,
+        4;1283;1284;1285;1286;,
+        4;1287;1288;1289;1290;,
+        4;1291;1292;1293;1294;,
+        4;1295;1296;1297;1298;,
+        3;1299;1300;1301;,
+        3;1302;1303;1304;,
+        4;1305;1306;1307;1308;,
+        4;1309;1310;1311;1312;,
+        4;1313;1314;1315;1316;,
+        4;1317;1318;1319;1320;,
+        4;1321;1322;1323;1324;,
+        4;1325;1326;1327;1328;,
+        4;1329;1330;1331;1332;,
+        4;1333;1334;1335;1336;,
+        4;1337;1338;1339;1340;,
+        4;1341;1342;1343;1344;,
+        4;1345;1346;1347;1348;,
+        4;1349;1350;1351;1352;,
+        4;1353;1354;1355;1356;,
+        4;1357;1358;1359;1360;,
+        3;1361;1362;1363;,
+        3;1364;1365;1366;,
+        4;1367;1368;1369;1370;,
+        4;1371;1372;1373;1374;,
+        4;1375;1376;1377;1378;,
+        4;1379;1380;1381;1382;,
+        4;1383;1384;1385;1386;,
+        4;1387;1388;1389;1390;,
+        4;1391;1392;1393;1394;,
+        4;1395;1396;1397;1398;,
+        4;1399;1400;1401;1402;,
+        4;1403;1404;1405;1406;,
+        4;1407;1408;1409;1410;,
+        4;1411;1412;1413;1414;,
+        4;1415;1416;1417;1418;,
+        4;1419;1420;1421;1422;,
+        3;1423;1424;1425;,
+        3;1426;1427;1428;,
+        4;1429;1430;1431;1432;,
+        4;1433;1434;1435;1436;,
+        4;1437;1438;1439;1440;,
+        4;1441;1442;1443;1444;,
+        4;1445;1446;1447;1448;,
+        4;1449;1450;1451;1452;,
+        4;1453;1454;1455;1456;,
+        4;1457;1458;1459;1460;,
+        4;1461;1462;1463;1464;,
+        4;1465;1466;1467;1468;,
+        4;1469;1470;1471;1472;,
+        4;1473;1474;1475;1476;,
+        4;1477;1478;1479;1480;,
+        4;1481;1482;1483;1484;,
+        3;1485;1486;1487;,
+        3;1488;1489;1490;,
+        4;1491;1492;1493;1494;,
+        4;1495;1496;1497;1498;,
+        4;1499;1500;1501;1502;,
+        4;1503;1504;1505;1506;,
+        4;1507;1508;1509;1510;,
+        4;1511;1512;1513;1514;,
+        4;1515;1516;1517;1518;,
+        4;1519;1520;1521;1522;,
+        4;1523;1524;1525;1526;,
+        4;1527;1528;1529;1530;,
+        4;1531;1532;1533;1534;,
+        4;1535;1536;1537;1538;,
+        4;1539;1540;1541;1542;,
+        4;1543;1544;1545;1546;,
+        3;1547;1548;1549;,
+        3;1550;1551;1552;,
+        4;1553;1554;1555;1556;,
+        4;1557;1558;1559;1560;,
+        4;1561;1562;1563;1564;,
+        4;1565;1566;1567;1568;,
+        4;1569;1570;1571;1572;,
+        4;1573;1574;1575;1576;,
+        4;1577;1578;1579;1580;,
+        4;1581;1582;1583;1584;,
+        4;1585;1586;1587;1588;,
+        4;1589;1590;1591;1592;,
+        4;1593;1594;1595;1596;,
+        4;1597;1598;1599;1600;,
+        4;1601;1602;1603;1604;,
+        4;1605;1606;1607;1608;,
+        3;1609;1610;1611;,
+        3;1612;1613;1614;,
+        4;1615;1616;1617;1618;,
+        4;1619;1620;1621;1622;,
+        4;1623;1624;1625;1626;,
+        4;1627;1628;1629;1630;,
+        4;1631;1632;1633;1634;,
+        4;1635;1636;1637;1638;,
+        4;1639;1640;1641;1642;,
+        4;1643;1644;1645;1646;,
+        4;1647;1648;1649;1650;,
+        4;1651;1652;1653;1654;,
+        4;1655;1656;1657;1658;,
+        4;1659;1660;1661;1662;,
+        4;1663;1664;1665;1666;,
+        4;1667;1668;1669;1670;,
+        3;1671;1672;1673;,
+        3;1674;1675;1676;,
+        4;1677;1678;1679;1680;,
+        4;1681;1682;1683;1684;,
+        4;1685;1686;1687;1688;,
+        4;1689;1690;1691;1692;,
+        4;1693;1694;1695;1696;,
+        4;1697;1698;1699;1700;,
+        4;1701;1702;1703;1704;,
+        4;1705;1706;1707;1708;,
+        4;1709;1710;1711;1712;,
+        4;1713;1714;1715;1716;,
+        4;1717;1718;1719;1720;,
+        4;1721;1722;1723;1724;,
+        4;1725;1726;1727;1728;,
+        4;1729;1730;1731;1732;,
+        3;1733;1734;1735;,
+        3;1736;1737;1738;,
+        4;1739;1740;1741;1742;,
+        4;1743;1744;1745;1746;,
+        4;1747;1748;1749;1750;,
+        4;1751;1752;1753;1754;,
+        4;1755;1756;1757;1758;,
+        4;1759;1760;1761;1762;,
+        4;1763;1764;1765;1766;,
+        4;1767;1768;1769;1770;,
+        4;1771;1772;1773;1774;,
+        4;1775;1776;1777;1778;,
+        4;1779;1780;1781;1782;,
+        4;1783;1784;1785;1786;,
+        4;1787;1788;1789;1790;,
+        4;1791;1792;1793;1794;,
+        3;1795;1796;1797;,
+        3;1798;1799;1800;,
+        4;1801;1802;1803;1804;,
+        4;1805;1806;1807;1808;,
+        4;1809;1810;1811;1812;,
+        4;1813;1814;1815;1816;,
+        4;1817;1818;1819;1820;,
+        4;1821;1822;1823;1824;,
+        4;1825;1826;1827;1828;,
+        4;1829;1830;1831;1832;,
+        4;1833;1834;1835;1836;,
+        4;1837;1838;1839;1840;,
+        4;1841;1842;1843;1844;,
+        4;1845;1846;1847;1848;,
+        4;1849;1850;1851;1852;,
+        4;1853;1854;1855;1856;,
+        3;1857;1858;1859;,
+        3;1860;1861;1862;,
+        4;1863;1864;1865;1866;,
+        4;1867;1868;1869;1870;,
+        4;1871;1872;1873;1874;,
+        4;1875;1876;1877;1878;,
+        4;1879;1880;1881;1882;,
+        4;1883;1884;1885;1886;,
+        4;1887;1888;1889;1890;,
+        4;1891;1892;1893;1894;,
+        4;1895;1896;1897;1898;,
+        4;1899;1900;1901;1902;,
+        4;1903;1904;1905;1906;,
+        4;1907;1908;1909;1910;,
+        4;1911;1912;1913;1914;,
+        4;1915;1916;1917;1918;,
+        3;1919;1920;1921;,
+        3;1922;1923;1924;,
+        4;1925;1926;1927;1928;,
+        4;1929;1930;1931;1932;,
+        4;1933;1934;1935;1936;,
+        4;1937;1938;1939;1940;,
+        4;1941;1942;1943;1944;,
+        4;1945;1946;1947;1948;,
+        4;1949;1950;1951;1952;,
+        4;1953;1954;1955;1956;,
+        4;1957;1958;1959;1960;,
+        4;1961;1962;1963;1964;,
+        4;1965;1966;1967;1968;,
+        4;1969;1970;1971;1972;,
+        4;1973;1974;1975;1976;,
+        4;1977;1978;1979;1980;,
+        3;1981;1982;1983;;
+      } //End of Sphere_001 Normals
+      MeshMaterialList { //Sphere_001 Material List
+        1;
+        1;
+        0;;
+        Material Default_Material {
+           0.800000; 0.800000; 0.800000; 0.800000;;
+           96.078431;
+           0.500000; 0.500000; 0.500000;;
+           0.000000; 0.000000; 0.000000;;
+        }
+      } //End of Sphere_001 Material List
+    } //End of Sphere_001 Mesh
+  } //End of Sphere
+} //End of Root Frame

BIN
Assets/Art/teapot.glb


BIN
Assets/Art/texture.dds


BIN
Assets/Art/texture.jpg


+ 3 - 0
Assets/Audio/Sources.txt

@@ -0,0 +1,3 @@
+blip.wav		http://www.a1freesoundeffects.com/	Downloaded Wed, June 23, 2004
+computerbeep3.wav	http://www.a1freesoundeffects.com/	Downloaded Wed, June 23, 2004
+SpaceGod7-Level2.mp3	http://www.themysterioush.net/		Submitted by the Artist known as 'the mysterious h'

BIN
Assets/Audio/SpaceGod7-Level2.ogg


BIN
Assets/Audio/blip.ogg


BIN
Assets/Audio/blip.wav


BIN
Assets/Audio/blip16.wav


BIN
Assets/Audio/computerbeep3.ogg


BIN
Assets/Audio/computerbeep3.wav


+ 96 - 0
Assets/Config/physics.xml

@@ -0,0 +1,96 @@
+<Physics>
+    <PhysicsMaterials>
+        <PlayDough restitution="0.05" friction="0.9"/>
+        <Normal restitution="0.25" friction="0.5"/>
+        <Bouncy restitution = "0.95" friction = "0.5"/>
+        <Slippery restitution = "0.25" friction = "0.0"/>
+    </PhysicsMaterials>
+
+<!--
+    // Physics Densities were grabbed from various resources, including:
+    // http://www.engineeringtoolbox.com/24_293.html
+    // http://www.simetric.co.uk/si_wood.htm
+    // http://www.phy.cmich.edu/people/andy/Physics110/Book/Chapters/Chapter8.htm
+-->
+    <DensityTable>
+        <!--  specific gravity (these numbers are easier to find) -->
+        <air>0.0013</air>
+        <water>1.000</water>
+
+        <!--  Synthetics -->
+        <styrofoam>0.0100</styrofoam>
+
+        <!--  Woods -->
+        <balsa>0.0170</balsa>
+        <bamboo>0.3500</bamboo>
+        <pine>0.5000</pine>
+        <oak>0.8300</oak>
+        <ebony>1.100</ebony>
+
+        <!--  Biologic -->
+        <blood>1.060</blood>
+        <bone>1.800</bone>
+
+        <!--  Metals and Stone -->
+        <silicon>2.400</silicon>
+        <aluminum>2.650</aluminum>
+        <asbestos>2.450</asbestos>
+        <barite>4.500</barite>
+        <basalt>3.350</basalt>
+        <bismuth>9.800</bismuth>
+        <borax>1.750</borax>
+        <boron>2.320</boron>
+        <brass>8.550</brass>
+        <brick>8.640</brick>
+        <bronze>8.400</bronze>
+        <calcium>4.580</calcium>
+        <carbon>1.950</carbon>
+        <chromium>7.100</chromium>
+        <clay>2.200</clay>
+        <coal>0.800</coal>
+        <cobalt>8.900</cobalt>
+        <copper>8.750</copper>
+        <diamond>3.510</diamond>
+        <dolomite>2.900</dolomite>
+        <epoxy>1.800</epoxy>
+        <glass>2.600</glass>
+        <crystal>2.950</crystal>
+        <granite>2.550</granite>
+        <gold>19.30</gold>
+        <hematite>5.200</hematite>
+        <iridium>21.60</iridium>
+        <castIron>7.200</castIron>
+        <wroughtIron>7.750</wroughtIron>
+        <limestone>2.400</limestone>
+        <lead>11.34</lead>
+        <magnetite>3.200</magnetite>
+        <manganese>7.420</manganese>
+        <magnesium>1.740</magnesium>
+        <marble>2.720</marble>
+        <Mercury>13.54</Mercury>
+        <Molybdenum>10.20</Molybdenum>
+        <Nickel>8.900</Nickel>
+        <Platinum>21.45</Platinum>
+        <Potassium>0.860</Potassium>
+        <Quartz>2.650</Quartz>
+        <Sandstone>2.300</Sandstone>
+        <Serpentine>2.750</Serpentine>
+        <Silver>10.50</Silver>
+        <Sodium>0.970</Sodium>
+        <Steel>7.800</Steel>
+        <Talc>2.700</Talc>
+        <Tar>1.200</Tar>
+        <Tellurium>6.120</Tellurium>
+        <Tin>7.350</Tin>
+        <Titanium>4.500</Titanium>
+        <Tungsten>19.22</Tungsten>
+        <Uranium>18.70</Uranium>
+        <Vanadium>5.960</Vanadium>
+        <Vinyl>1.800</Vinyl>
+        <Wool>1.320</Wool>
+        <Zinc>7.050</Zinc>
+
+        <Infinite>0.000</Infinite>
+    </DensityTable>
+</Physics>
+

+ 54 - 0
Assets/Editor/components.xml

@@ -0,0 +1,54 @@
+<Components>
+
+	<Component name="TransformComponent">
+		<Element name="Position" type="Vec3" fieldNames="x,y,z" />
+		<Element name="YawPitchRoll" type="Vec3" fieldNames="x,y,z" />
+	</Component>
+	
+	<Component name="PhysicsComponent">
+		<Element name="Shape" type="PhysicsShape" />
+		<Element name="Density" type="PhysicsDensity" />
+		<Element name="PhysicsMaterial" type="PhysicsMaterial" />
+		<Element name="Transform" type="TransformComponent" />
+    </Component>
+	
+	<Component name="LightRenderComponent">
+		<Element name="Color" type="RGBA" />
+		<Element name="Attenuation" type="Vec3" />
+		<Element name="Range" type="float" />
+		<Element name="Falloff" type="float" />
+		<Element name="Theta" type="float" />
+		<Element name="Phi" type="float" />		
+	</Component>
+	
+	<Component name="GridRenderComponent">
+		<Element name="Color" type="RGBA" />
+		<Element name="Texture" type="File" extensions="Image Files(*.BMP;*.JPG;*.GIF;*.DDS)|*.BMP;*.JPG;*.GIF;*.DDS|All files (*.*)|*.*"  />
+		<Element name="Division" type="int" />
+	</Component>
+	
+	<Component name="TeapotRenderComponent">
+		<Element name="Color" type="RGBA" />
+	</Component>
+
+	<Component name="ShaderMeshRenderComponent">
+		<Element name="D3D9MeshFile" type="File" extensions="DX9 X Files (*.x)|*.x" />
+		<Element name="D3D11MeshFile" type="File" extensions="DX11 Mesh Files (*.sdkmesh)|*.sdkmesh" />	
+	</Component>
+
+	<Component name="SkyRenderComponent">
+		<Element name="Texture" type="File" extensions="Image Files(*.BMP;*.JPG;*.GIF;*.DDS)|*.BMP;*.JPG;*.GIF;*.DDS|All files (*.*)|*.*"  />
+	</Component>
+
+	<Component name="AudioComponent">
+		<Element name="Sound" type="File" extensions="OGG (*.ogg)|*.ogg|WAVE (*.wav)|*.wav|All files (*.*)|*.*" />
+		<Element name="Loop" type="boolean" />
+		<Element name="FadeIn" type="float" />
+		<Element name="Volume" type="int" />
+	</Component>	
+	
+	<Component name="ScriptComponent">
+		<Element name="LUAFile" type="File" extensions="LUA (*.lua)|*.lua" />
+	</Component>
+	
+</Components>

+ 191 - 0
Assets/Effects/GameCode4.fx

@@ -0,0 +1,191 @@
+//--------------------------------------------------------------------------------------
+// GameCode4.fx - the shader file for GameCode4 (D3D9 renderer)
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//--------------------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------------------
+// This shader is not described in the 4th edition of Game Coding Complete. 
+// It was described in the 3rd edition, Chapter 14, page 509-514
+//--------------------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------------------
+// Global variables
+//--------------------------------------------------------------------------------------
+float4 g_MaterialAmbientColor;      // Material's ambient color
+float4 g_MaterialDiffuseColor;      // Material's diffuse color
+int g_nNumLights;
+
+// This shader can handle eight directional lights with a diffuse component and one ambient light
+float4 g_LightDir[8];               // Light's direction in world space
+float4 g_LightDiffuse[8];           // Light's diffuse color
+float4 g_LightAmbient;              // Light's ambient color
+float g_fAlpha;						// Alpha value (0.0 totally transparent, 1.0 opaque)
+
+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 = <g_MeshTexture>;
+    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 bool bTexture )
+{
+    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
+    float4 vTotalLightDiffuse = float4(0,0,0,0);
+    for(int i=0; i<g_nNumLights; i++ )
+        vTotalLightDiffuse += g_LightDiffuse[i] * max(0,dot(vNormalWorldSpace, g_LightDir[i]));
+        
+    Output.Diffuse.rgb = g_MaterialDiffuseColor * vTotalLightDiffuse + 
+                         g_MaterialAmbientColor * g_LightAmbient;   
+
+    Output.Diffuse.a = g_fAlpha; 
+    
+    // Just copy the texture coordinate through
+    if( bTexture ) 
+        Output.TextureUV = vTexCoord0; 
+    else
+        Output.TextureUV = 0; 
+    
+    return Output;    
+}
+
+
+//--------------------------------------------------------------------------------------
+// Pixel shader output structure
+//--------------------------------------------------------------------------------------
+struct PS_OUTPUT
+{
+    float4 RGBColor : COLOR0;  // Pixel color    
+};
+
+
+//--------------------------------------------------------------------------------------
+// This shader outputs the pixel's color by modulating the texture's
+//       color with diffuse material color
+//--------------------------------------------------------------------------------------
+PS_OUTPUT RenderScenePS( VS_OUTPUT In,
+                         uniform bool bTexture ) 
+{ 
+    PS_OUTPUT Output;
+
+    // Lookup mesh texture and modulate it with diffuse
+    if( bTexture )
+        Output.RGBColor = tex2D(MeshTextureSampler, In.TextureUV) * In.Diffuse;
+    else
+        Output.RGBColor = In.Diffuse;
+
+    return Output;
+}
+
+
+//--------------------------------------------------------------------------------------
+// Renders scene to render target
+//--------------------------------------------------------------------------------------
+
+technique RenderScene
+{
+    pass P0
+    {          
+        VertexShader = compile vs_2_0 RenderSceneVS( false );
+        PixelShader  = compile ps_2_0 RenderScenePS( false ); // trivial pixel shader (could use FF instead if desired)
+    }
+}
+
+
+technique RenderSceneWithAlpha
+{
+    pass P0
+    {          
+		AlphaBlendEnable	= true;
+		SrcBlend			= SrcAlpha;
+		DestBlend			= InvSrcAlpha;
+        VertexShader = compile vs_2_0 RenderSceneVS( false );
+        PixelShader  = compile ps_2_0 RenderScenePS( false ); // trivial pixel shader (could use FF instead if desired)
+    }
+}
+
+technique RenderSceneWithTexture
+{
+    pass P0
+    {          
+        VertexShader = compile vs_2_0 RenderSceneVS( true );
+        PixelShader  = compile ps_2_0 RenderScenePS( true ); // trivial pixel shader (could use FF instead if desired)
+    }
+}
+
+

+ 80 - 0
Assets/Effects/GameCode4_PS.hlsl

@@ -0,0 +1,80 @@
+//--------------------------------------------------------------------------------------
+// File: GameCode4_PS.hlsl - the pixel shader for GameCode4 (D3D11 renderer)
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//--------------------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------------------
+// Globals
+//--------------------------------------------------------------------------------------
+cbuffer cbObjectColors : register( b0 )
+{
+	float4		g_vDiffuseObjectColor	: packoffset( c0 );
+	float4		g_vAmbientObjectColor	: packoffset( c1 );
+	bool		g_bHasTexture			: packoffset( c2.x );
+};
+
+
+
+//--------------------------------------------------------------------------------------
+// Textures and Samplers
+//--------------------------------------------------------------------------------------
+Texture2D	g_txDiffuse : register( t0 );
+SamplerState g_samLinear : register( s0 );
+
+//--------------------------------------------------------------------------------------
+// Input / Output structures
+//--------------------------------------------------------------------------------------
+struct PS_INPUT
+{
+	float4 vDiffuse		: COLOR0;
+	float2 vTexcoord	: TEXCOORD0;
+};
+
+//--------------------------------------------------------------------------------------
+// Pixel Shader
+//--------------------------------------------------------------------------------------
+float4 GameCode4_PSMain( PS_INPUT Input ) : SV_TARGET
+{
+	float4 vOutputColor;
+
+	if (g_bHasTexture)
+		vOutputColor = g_txDiffuse.Sample( g_samLinear, Input.vTexcoord ) * Input.vDiffuse;
+	else
+		vOutputColor = Input.vDiffuse;
+	
+	return vOutputColor;
+}
+

+ 112 - 0
Assets/Effects/GameCode4_VS.hlsl

@@ -0,0 +1,112 @@
+//--------------------------------------------------------------------------------------
+// GameCode4_VSMain_VS.hlsl - The vertex shader file for GameCode4 (D3D11 renderer)
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//--------------------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------------------
+// Globals
+//--------------------------------------------------------------------------------------
+cbuffer cbMatrices : register( b0 )
+{
+	matrix		g_mWorldViewProjection	: packoffset( c0 );
+	matrix		g_mWorld				: packoffset( c4 );
+};
+
+cbuffer cbLights : register( b1 )
+{
+	float4		g_LightDiffuse[8];           // Light's diffuse color - we can support up to eight lights with this shader.
+	float4		g_LightDir[8];               // Light's direction in world space
+	float4		g_fAmbient;
+	int			g_nNumLights;
+};
+
+cbuffer cbObjectColors : register( b2 )
+{
+	float4		g_vDiffuseObjectColor	: packoffset( c0 );
+	float4		g_vAmbientObjectColor	: packoffset( c1 );
+	bool		g_bHasTexture			: packoffset( c2.x );
+};
+
+//--------------------------------------------------------------------------------------
+// Input / Output structures
+//--------------------------------------------------------------------------------------
+struct VS_INPUT
+{
+	float4 vPosition	: POSITION;
+	float3 vNormal		: NORMAL;
+	float2 vTexcoord	: TEXCOORD0;
+};
+
+struct VS_OUTPUT
+{
+	float4 vDiffuse		: COLOR0;
+	float2 vTexcoord	: TEXCOORD0;
+	float4 vPosition	: SV_POSITION;
+};
+
+//--------------------------------------------------------------------------------------
+// Vertex Shader
+//--------------------------------------------------------------------------------------
+VS_OUTPUT GameCode4_VSMain( VS_INPUT Input )
+{
+	VS_OUTPUT Output;
+	
+    float3 vNormalWorldSpace;
+	float dotProduct;
+	float4 dottedLightColor;
+
+	Output.vPosition = mul( Input.vPosition, g_mWorldViewProjection );
+	vNormalWorldSpace = mul( Input.vNormal, (float3x3)g_mWorld );
+	Output.vTexcoord = Input.vTexcoord;
+
+    // Compute simple directional lighting equation
+    float4 vTotalLightDiffuse = float4(0,0,0,0);
+    for(int i=0; i<g_nNumLights; i++ )
+	{
+		dotProduct = dot(vNormalWorldSpace, g_LightDir[i]);
+		dotProduct = max(0, dotProduct);
+		dottedLightColor = g_LightDiffuse[i] * dotProduct;
+        vTotalLightDiffuse += dottedLightColor;
+	}
+
+    Output.vDiffuse.rgb = g_vDiffuseObjectColor * vTotalLightDiffuse + 
+                         g_vAmbientObjectColor * g_fAmbient;   
+
+    Output.vDiffuse.a = g_vDiffuseObjectColor.a; 
+	
+	return Output;
+}
+

+ 27 - 0
Assets/Effects/GameCode4_frag.glsl

@@ -0,0 +1,27 @@
+#version 460 core
+
+//--------------------------------------------------------------------------------------
+// Globals
+//--------------------------------------------------------------------------------------
+layout(std140, binding = 2) uniform cbObjectColors
+{
+	vec4 		g_vDiffuseObjectColor;
+	vec4		g_vAmbientObjectColor;
+	bool		g_bHasTexture;
+};
+
+// interpolated values from vertex shader
+in vec2 uv;
+in vec4 diffuse;
+
+// output data
+out vec4 color;
+
+uniform sampler2D texture_sampler;
+
+void main() {
+	if (g_bHasTexture)
+		color = texture(texture_sampler, uv) * diffuse;
+	else
+		color = diffuse;
+}

+ 61 - 0
Assets/Effects/GameCode4_vert.glsl

@@ -0,0 +1,61 @@
+#version 460 core
+
+//--------------------------------------------------------------------------------------
+// Globals
+//--------------------------------------------------------------------------------------
+layout(std140, binding = 0) uniform cbMatrices
+{
+	mat4		g_mWorldViewProjection;
+	mat4 		g_mWorld;
+};
+
+layout(std140, binding = 1) uniform cbLights
+{
+	vec4		g_LightDiffuse[8];		// Light's diffuse color - up to 8 lights
+	vec4		g_LightDir[8];			// Light's direction in world space
+	vec4		g_fAmbient;
+	int			g_nNumLights;
+};
+
+layout(std140, binding = 2) uniform cbObjectColors
+{
+	vec4 		g_vDiffuseObjectColor;
+	vec4		g_vAmbientObjectColor;
+	bool		g_bHasTexture;
+};
+
+//--------------------------------------------------------------------------------------
+// Input / Output structures
+//--------------------------------------------------------------------------------------
+layout(location = 0) in vec3 position;
+layout(location = 1) in vec3 vNormal;
+layout(location = 2) in vec2 vertex_uv;
+
+out vec2 uv;
+out vec4 diffuse;
+
+void main() {
+
+	vec3 vNormalWorldSpace;
+	float dotProduct;
+	vec4 dottedLightColor;
+
+	gl_Position = g_mWorldViewProjection * vec4(position, 1.0);
+	vNormalWorldSpace = mat3(g_mWorld) * vNormal;
+	uv = vertex_uv;
+
+	// Compute simple directional lighting equation
+	vec4 vTotalLightDiffuse = vec4(0,0,0,0);
+	for(int i=0; i<g_nNumLights; i++)
+	{
+		dotProduct = dot(vNormalWorldSpace, g_LightDir[i].xyz);
+		dotProduct = max(0.0f, dotProduct);
+		dottedLightColor = g_LightDiffuse[i] * dotProduct;
+		vTotalLightDiffuse += dottedLightColor;
+	}
+
+	diffuse.rgb = (g_vDiffuseObjectColor * vTotalLightDiffuse +
+			g_vAmbientObjectColor * g_fAmbient).rgb;
+
+	diffuse.a = g_vDiffuseObjectColor.a;
+}

+ 172 - 0
Assets/Effects/LineDraw.hlsl

@@ -0,0 +1,172 @@
+//--------------------------------------------------------------------------------------
+// LineDraw.hlsl - Used to solid lines for GameCode4 (D3D11 renderer)
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//--------------------------------------------------------------------------------------
+
+// This shader was originally posted here: http://www.gamedev.net/topic/609031-hlsl-line-geometry-shader/
+
+
+
+Texture2D LineTexture;
+
+//-----------------------------------------------------------------------------
+// Constant Buffers
+//-----------------------------------------------------------------------------
+cbuffer cbRenderTarget
+{
+    float4 RenderTargetSize;			// x,y are the only ones used.
+}
+
+cbuffer cbChangePerFrame
+{
+    matrix WorldViewProjection;
+}
+
+cbuffer cbDiffuseColor
+{
+	float4 DiffuseColor;
+}
+
+//-----------------------------------------------------------------------------
+// Shader Input / Output Structures
+//-----------------------------------------------------------------------------
+struct VS_INPUT
+{
+    float4 Position : POSITION0;
+};
+
+struct GEO_IN
+{
+    float4 Position : POSITION0;
+};
+
+struct GEO_OUT
+{
+    float4 Position : SV_POSITION;
+    float2 TexCoord : TEXCOORD;
+};
+
+struct PS_OUTPUT 
+{
+    float4 Color : SV_Target0;
+};
+
+GEO_IN VS_LineV2(in VS_INPUT input)
+{
+    GEO_IN output;
+    output.Position = mul(input.Position, WorldViewProjection);
+    //output.Position = input.Position;
+    return output;
+}
+
+[maxvertexcount(6)]
+void GS(line GEO_IN points[2], inout TriangleStream<GEO_OUT> output)
+{
+    float4 p0 = points[0].Position;
+    float4 p1 = points[1].Position;
+
+    float w0 = p0.w;
+    float w1 = p1.w;
+
+    p0.xyz /= p0.w;
+    p1.xyz /= p1.w;
+
+    float3 line01 = p1 - p0;
+    float3 dir = normalize(line01);
+
+    // scale to correct window aspect ratio
+    float3 ratio = float3(RenderTargetSize.y, RenderTargetSize.x, 0);
+    ratio = normalize(ratio);
+
+    float3 unit_z = normalize(float3(0, 0, -1));
+
+    float3 normal = normalize(cross(unit_z, dir) * ratio);
+
+    float width = 0.005;
+
+    GEO_OUT v[4];
+
+    float3 dir_offset = dir * ratio * width;
+    float3 normal_scaled = normal * ratio * width;
+
+    float3 p0_ex = p0 - dir_offset;
+    float3 p1_ex = p1 + dir_offset;
+
+    v[0].Position = float4(p0_ex - normal_scaled, 1) * w0;
+    v[0].TexCoord = float2(0,0);
+
+    v[1].Position = float4(p0_ex + normal_scaled, 1) * w0;
+    v[1].TexCoord = float2(0,0);
+
+    v[2].Position = float4(p1_ex + normal_scaled, 1) * w1;
+    v[2].TexCoord = float2(0,0);
+
+    v[3].Position = float4(p1_ex - normal_scaled, 1) * w1;
+    v[3].TexCoord = float2(0,0);
+
+    output.Append(v[2]);
+    output.Append(v[1]);
+    output.Append(v[0]);
+
+    output.RestartStrip();
+
+    output.Append(v[3]);
+    output.Append(v[2]);
+    output.Append(v[0]);
+
+    output.RestartStrip();
+}
+
+PS_OUTPUT PS_LineV2(GEO_OUT input)
+{
+    PS_OUTPUT output;
+
+    //output.Color = LineTexture.Sample(LinearSampler, input.TexCoord);
+    //output.Color = float4(input.TexCoord.xy, 0, 1);
+    output.Color = DiffuseColor;
+	
+    return output;
+}
+
+technique10 LineV2Technique
+{
+    pass P0
+    {       
+        SetVertexShader(CompileShader(vs_4_0, VS_LineV2()));
+        SetGeometryShader(CompileShader(gs_4_0, GS()));
+        SetPixelShader(CompileShader(ps_4_0, PS_LineV2()));
+    }
+}

+ 58 - 0
Assets/Scripts/ActorManager.lua

@@ -0,0 +1,58 @@
+--========================================================================
+-- ActorManager.lua : Defines the ActorManager class
+--
+-- Part of the GameCode4 Application
+--
+-- GameCode4 is the sample application that encapsulates much of the source code
+-- discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+-- "Rez" Graham, published by Charles River Media. 
+-- ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+--
+-- If this source code has found it's way to you, and you think it has helped you
+-- in any way, do the authors a favor and buy a new copy of the book - there are 
+-- detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+-- by clicking here: 
+--    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+--
+-- There's a companion web site at http://www.mcshaffry.com/GameCode/
+-- 
+-- The source code is managed and maintained through Google Code: 
+--    http://code.google.com/p/gamecode4/
+--
+-- (c) Copyright 2012 Michael L. McShaffry and David Graham
+--
+-- This program is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser GPL v3
+-- as published by the Free Software Foundation.
+--
+-- 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 
+-- http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+--
+-- You should have received a copy of the GNU Lesser GPL v3
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+--
+--========================================================================
+
+-----------------------------------------------------------------------------------------------------------------------
+-- ActorManager													- Chapter 21, page 739
+-- This class manages the script representation of all actors in the game.
+-----------------------------------------------------------------------------------------------------------------------
+ActorManager = class(nil,
+{
+	_player = nil,  -- this will be filled automatically when player_teapot.xml is loaded
+});
+
+function ActorManager:AddPlayer(scriptObject)
+	if (self._player ~= nil) then
+		print("Attempting to add player to ActorManager when one already exists; id = " .. self._player:GetActorId());
+	end
+
+	-- add the new player regardless
+	self._player = scriptObject;
+
+	-- tell the human view that this is the controlled actor
+	QueueEvent(EventType.EvtData_Set_Controlled_Actor, self._player:GetActorId());
+end

+ 52 - 0
Assets/Scripts/LevelInit.lua

@@ -0,0 +1,52 @@
+--========================================================================
+-- LevelInit.lua : A script that's executed when the level is initializing
+--
+-- Part of the GameCode4 Application
+--
+-- GameCode4 is the sample application that encapsulates much of the source code
+-- discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+-- "Rez" Graham, published by Charles River Media. 
+-- ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+--
+-- If this source code has found it's way to you, and you think it has helped you
+-- in any way, do the authors a favor and buy a new copy of the book - there are 
+-- detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+-- by clicking here: 
+--    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+--
+-- There's a companion web site at http://www.mcshaffry.com/GameCode/
+-- 
+-- The source code is managed and maintained through Google Code: 
+--    http://code.google.com/p/gamecode4/
+--
+-- (c) Copyright 2012 Michael L. McShaffry and David Graham
+--
+-- This program is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser GPL v3
+-- as published by the Free Software Foundation.
+--
+-- 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 
+-- http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+--
+-- You should have received a copy of the GNU Lesser GPL v3
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+--
+--========================================================================
+
+require("scripts/actormanager.lua");
+
+-----------------------------------------------------------------------------------------------------------------------
+-- Global actor manager										- Chapter 21, page 738
+-----------------------------------------------------------------------------------------------------------------------
+g_actorMgr = ActorManager:Create();
+
+
+-----------------------------------------------------------------------------------------------------------------------
+-- constructor / destructor functions for actors
+-----------------------------------------------------------------------------------------------------------------------
+function AddPlayer(scriptObject)
+	g_actorMgr:AddPlayer(scriptObject);
+end

+ 1 - 0
Assets/Scripts/LevelPostInit.lua

@@ -0,0 +1 @@
+print("LevelPostInit.lua")

+ 171 - 0
Assets/Scripts/PreInit.lua

@@ -0,0 +1,171 @@
+--========================================================================
+-- PreInit.lua : Script that's run when the scripting system is initialized
+--
+-- Part of the GameCode4 Application
+--
+-- GameCode4 is the sample application that encapsulates much of the source code
+-- discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+-- "Rez" Graham, published by Charles River Media. 
+-- ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+--
+-- If this source code has found it's way to you, and you think it has helped you
+-- in any way, do the authors a favor and buy a new copy of the book - there are 
+-- detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+-- by clicking here: 
+--    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+--
+-- There's a companion web site at http://www.mcshaffry.com/GameCode/
+-- 
+-- The source code is managed and maintained through Google Code: 
+--    http://code.google.com/p/gamecode4/
+--
+-- (c) Copyright 2012 Michael L. McShaffry and David Graham
+--
+-- This program is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser GPL v3
+-- as published by the Free Software Foundation.
+--
+-- 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 
+-- http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+--
+-- You should have received a copy of the GNU Lesser GPL v3
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+--
+--========================================================================
+
+-- This file is run immediately after Lua is created but before the rest of the game initializes.  This is the place
+-- to put any language extentions or pure utility functions/classes you write.
+
+-----------------------------------------------------------------------------------------------------------------------
+-- Redifinition of require() and dofile().  This is needed to allow scripts to go through the resource system.
+-----------------------------------------------------------------------------------------------------------------------
+do
+	local OldRequire = require;  -- save the old require() function
+	local resourceIdMap = {};  -- map of resource id's we've already loaded
+
+	require = function(script)
+		-- If we haven't already loaded this file, try to load it now
+		if (not resourceIdMap[script]) then
+			if (LoadAndExecuteScriptResource(script)) then
+				resourceIdMap[script] = true;
+			else
+				-- failed to load file through the resource system so fall back to the old method
+				OldRequire(script)
+			end
+		end
+	end
+end
+
+do
+	local OldPrint = print;
+
+	print = function(text)
+		if (text ~= nil) then
+			Log(text);
+		else
+			Log("<nil>");
+		end
+	end
+end
+
+
+-----------------------------------------------------------------------------------------------------------------------
+-- Utility functions
+-----------------------------------------------------------------------------------------------------------------------
+Utils = {};
+
+function Utils.DumpTable(table)
+	for key, val in pairs(table) do
+		print(key, val);
+	end
+end
+
+-- private function used by Utils.DumpObject()
+function Utils._BuildMemberSet(obj, memberSet)
+	if (obj.__index ~= nil and obj ~= obj.__index) then
+		Utils._BuildMemberSet(obj.__index, memberSet);
+	end
+
+	for key, val in pairs(obj) do
+		if (key ~= "_index" and memberSet[key] == nil) then
+			memberSet[key] = true;
+		end
+	end
+end
+
+function Utils.DumpObject(obj)
+	-- There might be copies of the same variable at various levels in the hierarchy so we need to build an
+	-- exclusive set of names.
+	local memberSet = {};
+	Utils._BuildMemberSet(obj, memberSet);
+
+	-- Loop through the set of member names and print them out, along with the value from the original object's
+	-- perspective.
+	for key,val in pairs(memberSet) do
+		print(key, obj[key]);
+	end
+end
+
+-----------------------------------------------------------------------------------------------------------------------
+-- Classes & Inheritance								- Chapter 12, page 349
+-----------------------------------------------------------------------------------------------------------------------
+function class(baseClass, body)
+	local ret = body or {};
+
+	-- if there's a base class, attach our new class to it
+	if (baseClass ~= nil) then
+		setmetatable(ret, ret);
+		ret.__index = baseClass;
+		ret.base = baseClass;
+	end
+
+	-- Add the Create() function.  This will end up being added to each subclass which isn't ideal.  This 
+	-- function should probably be stored in a single place so we only have to create it once.
+	-- 		-self: The self pointer that's calling this function.
+	--		-constructionData: The table sent in as construction data.  Think of it like a constructor.
+	--		-originalSubClass: Used for recursion.  Don't pass anything into this parameter, it's filled 
+	--						   automatically.  It's used in case the C++ side needs access to the leaf 
+	--						   subclass that is being instantiated.  For an example, see ScriptProcess 
+	--						   in C++.
+	ret.Create = function(self, constructionData, originalSubClass)
+		local obj;
+		if (self.__index ~= nil) then
+			if (originalSubClass ~= nil) then
+				obj = self.__index:Create(constructionData, originalSubClass);
+			else
+				obj = self.__index:Create(constructionData, self);
+			end
+		else
+			obj = constructionData or {};
+		end
+
+		setmetatable(obj, obj);
+		obj.__index = self;
+
+		-- copy any operators over
+		if (self.__operators ~= nil) then
+			for key, val in pairs(self.__operators) do
+				obj[key] = val;
+			end
+		end
+
+		return obj;
+	end
+
+	-- Returns true if otherClass appears in this objects class hierarchy anywhere.
+	ret.IsInstance = function(self, otherClass)
+		local cls = self.__index;
+		while cls do
+			if cls == otherClass then
+				return true
+			end
+			cls = cls.base
+		end
+		return false
+	end
+
+	return ret;
+end

+ 53 - 0
Assets/Scripts/test.lua

@@ -0,0 +1,53 @@
+--========================================================================
+-- tests.lua : General testing & debugging functions
+--
+-- Part of the GameCode4 Application
+--
+-- GameCode4 is the sample application that encapsulates much of the source code
+-- discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+-- "Rez" Graham, published by Charles River Media. 
+-- ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+--
+-- If this source code has found it's way to you, and you think it has helped you
+-- in any way, do the authors a favor and buy a new copy of the book - there are 
+-- detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+-- by clicking here: 
+--    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+--
+-- There's a companion web site at http://www.mcshaffry.com/GameCode/
+-- 
+-- The source code is managed and maintained through Google Code: 
+--    http://code.google.com/p/gamecode4/
+--
+-- (c) Copyright 2012 Michael L. McShaffry and David Graham
+--
+-- This program is free software; you can redistribute it and/or
+-- modify it under the terms of the GNU Lesser GPL v3
+-- as published by the Free Software Foundation.
+--
+-- 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 
+-- http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+--
+-- You should have received a copy of the GNU Lesser GPL v3
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+--
+--========================================================================
+
+print("Loading script");
+
+function TestEventHandler(eventData)
+	print("Event Received in Lua: " .. eventData);
+	eventData = eventData + 1;
+	QueueEvent(EventType.EvtData_ScriptEventTest_FromLua, eventData)
+end
+
+function RegisterListener()
+	RegisterEventListener(EventType.EvtData_ScriptEventTest_ToLua, TestEventHandler);
+end
+
+RegisterListener();
+
+print("Script loaded");

+ 25 - 0
Assets/Strings/English.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<strings>
+  <string id="IDS_QUESTION_WHERES_THE_CD" value="Please insert the game CD, and hit retry." />
+  <string id="IDS_ALERT" value="Alert" />
+  <string id="IDS_QUESTION" value="Question" />
+  <string id="IDS_QUESTION_QUIT_GAME" value="Do you really\n want to quit\n the game?" />
+  <string id="IDS_INITIALIZING" value="Initializing" />
+  <string id="IDS_OK" value="Ok" hotkey="O" />
+  <string id="IDS_YES" value="Yes" hotkey="Y"/>
+  <string id="IDS_CANCEL" value="Cancel" />
+  <string id="IDS_NO" value="No" hotkey="N" />
+  <string id="IDS_CONTINUE" value="Continue" hotkey="C" />
+  <string id="IDS_TRYAGAIN" value="Try Again" hotkey="T" />
+  <string id="IDS_RETRY" value="Retry" hotkey="R" />
+  <string id="IDS_PLAYER" value="Player" />
+  <string id="IDS_WAITING" value="Waiting for Players..." />
+  <string id="IDS_RUNNING" value="Game in Progress!" />
+  <string id="IDS_LOADING" value="Loading Game..." />
+  <string id="IDS_NOPHYSICS" value="Physics Has Been Disabled... This Game Will Be Boring." />
+  <string id="IDS_CONTROLS_HEADER" value="Controls (F1 to hide):" />
+  <string id="IDS_CONTROLS" value="Move: WASD\nFire: Left Mouse Button\nF9:  Control Teapot\nF11: Free camera\nQuit: ESC" />
+  <string id="IDS_CAMERA_LOCATION" value="Camera location: %.2f, %.2f, %.2f" />
+  <string id="IDS_RUSSIAN" value="ценность Мир имеет много языков" />
+  <string id="IDS_CHINESE" value="价值世界有很多语言" />
+</strings>

+ 27 - 0
Assets/World/World.xml

@@ -0,0 +1,27 @@
+<World>
+  
+    <!-- A list of static actors to load.  Static actors have no game view attached.  This is for stuff like 
+    level geometry.-->
+
+    <StaticActors>
+      <Actor resource="actors/grid.xml" />
+      <Actor resource="actors/light.xml" />
+  	  <Actor resource="actors/afternoon_sky.xml" />
+      <!-- <Actor resource="actors/music.xml" /> -->
+
+
+<!--
+        <Actor resource="actors/player_spawner.xml" />
+        <Actor resource="actors/ai_spawner_0.xml" />
+        <Actor resource="actors/ai_spawner_1.xml" />
+        <Actor resource="actors/ai_spawner_2.xml" />
+        <Actor resource="actors/ai_spawner_3.xml" />
+-->
+    </StaticActors>
+
+
+    <!-- The preLoad script is executed as the first operation when the level is loading.  The postLoad script 
+    if executed as the last step in the level loading process. -->
+    <Script preLoad="scripts/LevelInit.lua" postLoad="scripts/LevelPostInit.lua"/>
+
+</World>

+ 48 - 0
Assets/World/WorldInstances.xml

@@ -0,0 +1,48 @@
+<World>
+  
+    <!-- A list of static actors to load.  Static actors have no game view attached.  This is for stuff like 
+    level geometry.-->
+
+    <StaticActors>
+      <Actor resource="actors/grid.xml">
+		<GridRenderComponent>
+			<Color r="0.4" g="0.4" b="0.4" a="1.0"/>
+			<Division>100</Division>
+		</GridRenderComponent>
+	  </Actor>
+      <Actor resource="actors/grid.xml">
+		<TransformComponent>
+			<Position x="-10" y="0" z="-10"/>
+			<YawPitchRoll x="0" y="0" z="-15"/>
+		</TransformComponent>
+		<GridRenderComponent>
+			<Color r="0.2" g="0.8" b="0.2" a="1.0"/>
+			<Division>10</Division>
+		</GridRenderComponent>
+		<!-- <PhysicsComponent>
+			<RigidBodyTransform>
+				<Scale x="5" y="0.01" z="5" />  
+			</RigidBodyTransform>
+		</PhysicsComponent>	 -->	
+	  </Actor>
+	  
+      <Actor resource="actors/light.xml" />
+<!--
+        <Actor resource="actors/player_spawner.xml" />
+        <Actor resource="actors/ai_spawner_0.xml" />
+        <Actor resource="actors/ai_spawner_1.xml" />
+        <Actor resource="actors/ai_spawner_2.xml" />
+        <Actor resource="actors/ai_spawner_3.xml" />
+-->
+
+	  <Actor resource="actors/afternoon_sky.xml" />
+      <Actor resource="actors/music.xml" />
+
+
+    </StaticActors>
+
+    <!-- The preLoad script is executed as the first operation when the level is loading.  The postLoad script 
+    if executed as the last step in the level loading process. -->
+    <Script preLoad="scripts/LevelInit.lua" postLoad="scripts/LevelPostInit.lua"/>
+
+</World>

+ 8 - 0
CMakeLists.txt

@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.24)
+
+project(GCC4 LANGUAGES C CXX)
+
+SET(CMAKE_CXX_STANDARD 20)
+
+add_subdirectory(Vendor)
+add_subdirectory(Source)

BIN
Game/Assets.zip


+ 7 - 0
Game/Logging.xml

@@ -0,0 +1,7 @@
+<Logging>
+    <Log tag="Script" debugger="1" file="0"/>
+    <Log tag="Lua" debugger="1" file="0"/>
+    <Log tag="Actor" debugger="1" file="0"/>
+    <Log tag="Events" debugger="1" file="0"/>
+    <Log tag="EventLoop" debugger="0" file="0"/>
+</Logging>

+ 7 - 0
Game/PlayerOptions.xml

@@ -0,0 +1,7 @@
+<PlayerOptions>
+  <Graphics renderer="OpenGL 4.6" width="1072" height="768" runfullspeed="no" />
+  <Sound sfxVolume="100" musicVolume="100"/>
+  <Multiplayer expectedPlayers="1" numAIs="1" maxAIs="4" maxPlayers="4" listenPort="57" gameHost="MrMike-m1710" />
+  <ResCache useDevelopmentDirectories="yes" /> 
+  <PhysicsDebug DrawWireFrame="yes" DrawContactPoints="yes" />
+</PlayerOptions>

+ 8 - 0
README.md

@@ -0,0 +1,8 @@
+## 3rd Party Dependencies
+
++ tinyxml
+
+## Changes From The Original
+
+### Added `Source/Unix/GameCodeStd.h`
+

+ 154 - 0
Source/CMakeLists.txt

@@ -0,0 +1,154 @@
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+
+find_package(PkgConfig REQUIRED)
+find_package(OpenGL REQUIRED)
+find_package(GLEW REQUIRED)
+
+pkg_check_modules(TINYXML REQUIRED IMPORTED_TARGET tinyxml)
+
+SET(GCC4_HEADERS
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/Actor.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/ActorComponent.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/ActorFactory.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/AudioComponent.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/BaseScriptComponent.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/RenderComponent.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/ScriptComponentInterface.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/TransformComponent.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Debugging/Logger.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/EventManager/EventManager.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/EventManager/EventManagerImpl.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/EventManager/Events.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/GameCode4/BaseGameLogic.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/GameCode4/GameCode.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/GameCode4/interfaces.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Geometry.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Lights.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Material.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Mesh.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/MovementController.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/OpenGLRenderer.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Scene.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/SceneNodes.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Shaders.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Sky.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/LUAScripting/LuaStateManager.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/LUAScripting/ScriptEvent.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/LUAScripting/ScriptExports.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/LUAScripting/ScriptProcess.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/LUAScripting/ScriptResource.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Mainloop/Initialization.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Mainloop/Process.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Multicore/CriticalSection.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/ResourceCache/ResCache.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/ResourceCache/XmlResource.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/ResourceCache/ZipFile.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Unix/GameCodeStd.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/UserInterface/HumanView.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Utilities/Dialogs.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Utilities/Math.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Utilities/String.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Utilities/templates.h
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Utilities/types.h
+)
+
+SET(GCC4_SOURCES
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/Actor.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/ActorFactory.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/AudioComponent.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/BaseScriptComponent.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/RenderComponent.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Actors/TransformComponent.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Debugging/Logger.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/EventManager/EventManager.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/EventManager/EventManagerImpl.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/EventManager/Events.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/GameCode4/BaseGameLogic.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/GameCode4/GameCode.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/GameCode4/GameCode4.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Geometry.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Lights.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Material.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Mesh.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/MovementController.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/OpenGLRenderer.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Scene.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/SceneNodes.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Shaders.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Graphics3D/Sky.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/LUAScripting/LuaStateManager.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/LUAScripting/ScriptEvent.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/LUAScripting/ScriptExports.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/LUAScripting/ScriptProcess.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/LUAScripting/ScriptResource.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Mainloop/Initialization.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Mainloop/Process.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/ResourceCache/ResCache.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/ResourceCache/XmlResource.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/ResourceCache/ZipFile.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Unix/GameCodeStd.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/UserInterface/HumanView.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Utilities/Dialogs.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Utilities/Math.cpp
+	${PROJECT_SOURCE_DIR}/Source/GCC4/Utilities/String.cpp
+)
+
+add_library(gcc4 ${GCC4_HEADERS} ${GCC4_SOURCES})
+
+target_link_libraries(gcc4 PRIVATE PkgConfig::TINYXML)
+target_link_libraries(gcc4 PRIVATE GLEW::GLEW OpenGL::GL SDL3::SDL3 SDL3_image::SDL3_image)
+target_link_libraries(gcc4 PRIVATE imgui)
+target_link_libraries(gcc4 PUBLIC sol2::sol2 lua)
+target_link_libraries(gcc4 PUBLIC fastdelegate)
+target_link_libraries(gcc4 PUBLIC assimp)
+
+# target_include_directories(gcc4 PUBLIC ${LUA_INCLUDE_DIR})
+
+SET(TEAPOT_HEADERS
+	${PROJECT_SOURCE_DIR}/Source/GCC4/GameCode4/GameCode.h
+	${PROJECT_SOURCE_DIR}/Source/TeapotWars/TeapotEvents.h
+	${PROJECT_SOURCE_DIR}/Source/TeapotWars/TeapotWarsView.h
+	${PROJECT_SOURCE_DIR}/Source/TeapotWars/Unix/TeapotWars.h
+	${PROJECT_SOURCE_DIR}/Source/TeapotWars/Unix/TeapotWarsStd.h
+)
+
+SET(TEAPOT_SOURCES
+	${PROJECT_SOURCE_DIR}/Source/TeapotWars/TeapotEvents.cpp
+	${PROJECT_SOURCE_DIR}/Source/TeapotWars/TeapotWars.cpp
+	${PROJECT_SOURCE_DIR}/Source/TeapotWars/TeapotWarsView.cpp
+)
+
+add_executable(teapot-wars ${TEAPOT_HEADERS} ${TEAPOT_SOURCES} ${GCC4_HEADERS})
+
+target_link_libraries(teapot-wars PRIVATE 
+	gcc4
+	GLEW::GLEW
+	OpenGL::GL
+	SDL3::SDL3
+	SDL3_image::SDL3_image
+	imgui
+	${CMAKE_DL_LIBS}
+)
+
+target_compile_options(gcc4 PRIVATE -Wall -Wextra -Wpedantic)
+target_compile_features(gcc4 PUBLIC cxx_std_20)
+
+target_compile_options(teapot-wars PRIVATE -Wall -Wextra -Wpedantic)
+target_compile_features(teapot-wars PUBLIC cxx_std_20)
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+
+add_custom_command(
+    TARGET teapot-wars PRE_BUILD
+        COMMAND ${CMAKE_COMMAND} -E copy_directory
+                ${PROJECT_SOURCE_DIR}/Game
+                ${CMAKE_BINARY_DIR}/)
+
+add_custom_command(
+    TARGET teapot-wars PRE_BUILD
+        COMMAND ${CMAKE_COMMAND} -E copy_directory
+                ${PROJECT_SOURCE_DIR}/Assets
+                ${CMAKE_BINARY_DIR}/Assets)

+ 92 - 0
Source/GCC4/Actors/Actor.cpp

@@ -0,0 +1,92 @@
+//========================================================================
+// Actor.cpp - Implements the Actor class
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+
+#include "../Unix/GameCodeStd.h"
+#include "Actor.h"
+#include "ActorComponent.h"
+#include "../Utilities/String.h"
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// Actor
+// Chapter 6, page 165
+//---------------------------------------------------------------------------------------------------------------------
+Actor::Actor(ActorId id)
+{
+    m_id = id;
+    m_type = "Unknown";
+
+	// [mrmike] added post press - this is an editor helper
+	m_resource = "Unknown";
+}
+
+Actor::~Actor(void)
+{
+    GCC_LOG("Actor", std::string("Destroying Actor ") + ToStr(m_id));
+    GCC_ASSERT(m_components.empty());  // [rez] if this assert fires, the actor was destroyed without calling Actor::Destroy()
+}
+
+bool Actor::Init(TiXmlElement* pData)
+{
+	GCC_LOG("Actor", std::string("Initializing Actor ") + ToStr(m_id));
+
+	m_type = pData->Attribute("type");
+	m_resource = pData->Attribute("resource");
+	return true;
+}
+
+void Actor::PostInit(void)
+{
+	for (ActorComponents::iterator it = m_components.begin(); it != m_components.end(); ++it)
+	{
+		it->second->VPostInit();
+	}
+}
+
+void Actor::Destroy(void)
+{
+	m_components.clear();
+}
+
+
+void Actor::AddComponent(StrongActorComponentPtr pComponent)
+{
+	std::pair<ActorComponents::iterator, bool> success = m_components.insert(std::make_pair(pComponent->VGetId(), pComponent));
+	GCC_ASSERT(success.second);
+}

+ 114 - 0
Source/GCC4/Actors/Actor.h

@@ -0,0 +1,114 @@
+#pragma once
+//========================================================================
+// Actor.h - Defines the Actor class
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "ActorComponent.h"
+
+class TiXmlElement;
+typedef std::string ActorType;
+
+//---------------------------------------------------------------------------------------------------------------------
+// Actor class
+// Chapter 6, page 165
+//---------------------------------------------------------------------------------------------------------------------
+class Actor
+{
+	friend class ActorFactory;
+	
+public:
+
+	typedef std::map<ComponentId, StrongActorComponentPtr> ActorComponents;
+
+private:
+    ActorId m_id;					// unique id for the actor
+    ActorComponents m_components;	// all components this actor has
+    ActorType m_type;
+
+    // [mrmike] - these were added post press as editor helpers, but will also be great for save game files if we ever make them.
+	std::string m_resource;			// the XML file from which this actor was initialized (considered the "Archetype" file)
+
+public:
+	explicit Actor(ActorId id);
+	~Actor(void);
+
+	bool Init(TiXmlElement* pData);
+	void PostInit(void);
+	void Destroy(void);
+
+	// accessors
+	ActorId GetId(void) const { return m_id; }
+	ActorType GetType(void) const { return m_type; }
+
+	// template function for retrieving components
+	template <class ComponentType>
+	std::weak_ptr<ComponentType> GetComponent(ComponentId id)
+	{
+		ActorComponents::iterator findIt = m_components.find(id);
+		if (findIt != m_components.end())
+		{
+			StrongActorComponentPtr pBase(findIt->second);
+			std::shared_ptr<ComponentType> pSub(std::static_pointer_cast<ComponentType>(pBase));  // cast to subclass version of the pointer
+			std::weak_ptr<ComponentType> pWeakSub(pSub);  // convert strong pointer to weak pointer
+			return pWeakSub; // return the weak pointer
+		}
+		else
+		{
+			return std::weak_ptr<ComponentType>();
+		}
+	}
+
+	template <class ComponentType>
+	std::weak_ptr<ComponentType> GetComponent(const char *name)
+	{
+		ComponentId id = ActorComponent::GetIdFromName(name);
+		ActorComponents::iterator findIt = m_components.find(id);
+		if (findIt != m_components.end())
+		{
+			StrongActorComponentPtr pBase(findIt->second);
+			std::shared_ptr<ComponentType> pSub(std::static_pointer_cast<ComponentType>(pBase));  // cast to subclass version of the pointer
+			std::weak_ptr<ComponentType> pWeakSub(pSub);  // convert strong pointer to weak pointer
+			return pWeakSub; // return the weak pointer
+		}
+		else
+		{
+			return std::weak_ptr<ComponentType>();
+		}
+	}
+
+	void AddComponent(StrongActorComponentPtr pComponent);
+};

+ 76 - 0
Source/GCC4/Actors/ActorComponent.h

@@ -0,0 +1,76 @@
+#pragma once
+//========================================================================
+// ActorComponent.h - Defines the base class for a component that can be attached to an actor
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Utilities/String.h"
+
+class TiXmlElement;
+
+//---------------------------------------------------------------------------------------------------------------------
+// ActorComponent class
+// Chapter 6, page 167
+//---------------------------------------------------------------------------------------------------------------------
+class ActorComponent
+{
+	friend class ActorFactory;
+
+protected:
+	StrongActorPtr m_pOwner;
+
+public:
+	// These functions are meant to be overridden by the implementation classes of the components.
+	virtual bool VInit(TiXmlElement* pData) = 0;
+	virtual void VPostInit(void) { }
+	// virtual void VUpdate(int deltaMs) { }
+	virtual void VOnChanged(void) { }				// [mrmike] - added post-press
+
+	// for the editor
+    virtual TiXmlElement* VGenerateXml(void) = 0;
+
+	// This function should be overridden by the interface class.
+	virtual ComponentId VGetId(void) const { return GetIdFromName(VGetName()); }
+	virtual const char *VGetName() const = 0;
+	static ComponentId GetIdFromName(const char* componentStr)
+	{
+		unsigned long rawId = HashedString::hash_name(componentStr);
+		return rawId;
+	}
+
+private:
+	void SetOwner(StrongActorPtr pOwner) { m_pOwner = pOwner; }
+};

+ 191 - 0
Source/GCC4/Actors/ActorFactory.cpp

@@ -0,0 +1,191 @@
+//========================================================================
+// ActorFactory.cpp : Creates actors from components
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+#include "ActorFactory.h"
+#include "../ResourceCache/XmlResource.h"
+#include "AudioComponent.h"
+#include "RenderComponent.h"
+#include "TransformComponent.h"
+#include "BaseScriptComponent.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+// Factory class definition
+// Chapter 6, page 161
+//---------------------------------------------------------------------------------------------------------------------
+ActorFactory::ActorFactory(void)
+{
+	m_lastActorId = INVALID_ACTOR_ID;
+
+	m_componentFactory.Register<TransformComponent>(ActorComponent::GetIdFromName(TransformComponent::g_Name));
+	// m_componentFactory.Register<MeshRenderComponent>(ActorComponent::GetIdFromName(MeshRenderComponent::g_Name));
+	// m_componentFactory.Register<SphereRenderComponent>(ActorComponent::GetIdFromName(SphereRenderComponent::g_Name));
+	// m_componentFactory.Register<PhysicsComponent>(ActorComponent::GetIdFromName(PhysicsComponent::g_Name));
+	m_componentFactory.Register<TeapotRenderComponent>(ActorComponent::GetIdFromName(TeapotRenderComponent::g_Name));
+	m_componentFactory.Register<GridRenderComponent>(ActorComponent::GetIdFromName(GridRenderComponent::g_Name));
+	m_componentFactory.Register<LightRenderComponent>(ActorComponent::GetIdFromName(LightRenderComponent::g_Name));
+	m_componentFactory.Register<SkyRenderComponent>(ActorComponent::GetIdFromName(SkyRenderComponent::g_Name));
+	m_componentFactory.Register<AudioComponent>(ActorComponent::GetIdFromName(AudioComponent::g_Name));
+
+	// // FUTURE WORK - certainly don't need to do this now, but the following stuff should be in a TeapotWarsActorFactory, eh?
+	// m_componentFactory.Register<AmmoPickup>(ActorComponent::GetIdFromName(AmmoPickup::g_Name));
+	// m_componentFactory.Register<HealthPickup>(ActorComponent::GetIdFromName(HealthPickup::g_Name));
+	m_componentFactory.Register<BaseScriptComponent>(ActorComponent::GetIdFromName(BaseScriptComponent::g_Name));
+}
+
+StrongActorPtr ActorFactory::CreateActor(
+		const char* actorResource,
+		TiXmlElement *overrides,
+		std::optional<const glm::mat4> pInitialTransform,
+		const ActorId serversActorId
+) {
+	TiXmlElement* pRoot = XmlResourceLoader::LoadAndReturnRootXmlElement(actorResource);
+	if (!pRoot)
+	{
+		GCC_ERROR("Failed to create actor from resource: " + std::string(actorResource));
+		return StrongActorPtr();
+	}
+
+	// create the actor instance
+	ActorId nextActorId = serversActorId;
+	if (nextActorId == INVALID_ACTOR_ID)
+	{
+		nextActorId = GetNextActorId();
+	}
+	StrongActorPtr pActor(GCC_NEW Actor(nextActorId));
+	if (!pActor->Init(pRoot))
+	{
+		GCC_ERROR("Failed to initialize actor: " + std::string(actorResource));
+		return StrongActorPtr();
+	}
+
+	bool initialTransformSet = false;
+
+	// Loop through each child element and load the componet
+	for (TiXmlElement* pNode = pRoot->FirstChildElement(); pNode; pNode = pNode->NextSiblingElement())
+	{
+		StrongActorComponentPtr pComponent(VCreateComponent(pNode));
+		if (pComponent)
+		{
+			pActor->AddComponent(pComponent);
+			pComponent->SetOwner(pActor);
+		}
+		else
+		{
+			// If an error occurs, we kill the actor and bail.  We could keep going, but the actor is will only be 
+			// partially complete so it's not worth it.  Note that the pActor instance will be destroyed because it
+			// will fall out of scope with nothing else pointing to it.
+			// [munnellg] I'm pretty sure this leaks because you need to call Actor::Destroy before actor is destructed
+			return StrongActorPtr();
+		}
+	}
+
+	if (overrides)
+	{
+		ModifyActor(pActor, overrides);
+	}
+
+	// This is a bit of a hack to get the initial transform of the transform component set before the 
+	// other components (like PhysicsComponent) read it.
+	std::shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(pActor->GetComponent<TransformComponent>(TransformComponent::g_Name));
+	if (pInitialTransform && pTransformComponent)
+	{
+		pTransformComponent->SetPosition(geometry::GetPosition(pInitialTransform.value()));
+	}
+
+	// Now that the actor has been fully created, run the post init phase
+    pActor->PostInit();
+
+    return pActor;
+}
+
+StrongActorComponentPtr ActorFactory::VCreateComponent(TiXmlElement* pData)
+{
+	const char* name = pData->Value();
+	StrongActorComponentPtr pComponent(m_componentFactory.Create(ActorComponent::GetIdFromName(name)));
+	
+	// initialize the component if we found one
+	if (pComponent)
+	{
+		if (!pComponent->VInit(pData))
+		{
+			GCC_ERROR("Component failed to initialize: " + std::string(name));
+			return StrongActorComponentPtr();
+		}
+	}
+	else
+	{
+		GCC_ERROR("Couldn't find ActorComponent named " + std::string(name));
+		return StrongActorComponentPtr(); // fail
+	}
+
+	// pComponent will be NULL if the component wasn't found.  This isn't necessarily an error since you might have a 
+    // custom CreateComponent() function in a sub class.
+	return pComponent;
+}
+
+
+void ActorFactory::ModifyActor(StrongActorPtr pActor, TiXmlElement* overrides)
+{
+	// Loop through each child element and load the element
+	for (TiXmlElement* pNode = overrides->FirstChildElement(); pNode; pNode = pNode->NextSiblingElement())
+	{
+		ComponentId componentId = ActorComponent::GetIdFromName(pNode->Value());
+		StrongActorComponentPtr pComponent = MakeStrongPtr(pActor->GetComponent<ActorComponent>(componentId));
+		if (pComponent)
+		{
+			pComponent->VInit(pNode);
+
+			// [mrmike] - added post press to ensure that components that need it have
+			//            Events generated that can notify subsystems when changes happen.
+			//            This was done to have SceneNode derived classes respond to RenderComponent
+			//            changes.
+
+			pComponent->VOnChanged();
+		}
+		else
+		{
+			pComponent = VCreateComponent(pNode);
+			if (pComponent)
+			{
+				pActor->AddComponent(pComponent);
+				pComponent->SetOwner(pActor);
+			}
+		}
+	}
+}

+ 71 - 0
Source/GCC4/Actors/ActorFactory.h

@@ -0,0 +1,71 @@
+#pragma once
+//========================================================================
+// ActorFactory.h - Defines a factory for creating actors & components
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Utilities/templates.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+// ActorFactory class
+// Chapter 6, page 161
+//---------------------------------------------------------------------------------------------------------------------
+class ActorFactory
+{
+	ActorId m_lastActorId;
+
+protected:
+	GenericObjectFactory<ActorComponent, ComponentId> m_componentFactory;
+
+public:
+	ActorFactory(void);
+
+	StrongActorPtr CreateActor(
+		const char* actorResource,
+		TiXmlElement* overrides,
+		std::optional<const glm::mat4> initialTransform,
+		const ActorId serversActorId
+	);
+	void ModifyActor(StrongActorPtr pActor, TiXmlElement* overrides);
+
+//protected:
+    // [rez] This function can be overridden by a subclass so you can create game-specific C++ components.  If you do
+    // this, make sure you call the base-class version first.  If it returns NULL, you know it's not an engine component.
+    virtual StrongActorComponentPtr VCreateComponent(TiXmlElement* pData);
+
+private:
+	ActorId GetNextActorId(void) { ++m_lastActorId; return m_lastActorId; }
+};

+ 121 - 0
Source/GCC4/Actors/AudioComponent.cpp

@@ -0,0 +1,121 @@
+#pragma once
+//========================================================================
+// AudioComponent.cpp : A component for attaching sounds to an actor
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+
+#include "AudioComponent.h"
+#include "../Utilities/String.h"
+// #include "../Audio/SoundProcess.h"
+// #include "../MainLoop/ProcessManager.h"
+#include "../UserInterface/HumanView.h"
+
+const char* AudioComponent::g_Name = "AudioComponent";
+
+AudioComponent::AudioComponent()
+{
+	m_audioResource = "";
+	m_looping = false;
+	m_fadeInTime = 0.0f;
+	m_volume = 100;
+}
+
+bool AudioComponent::VInit(TiXmlElement* pData)
+{
+	TiXmlElement* pTexture = pData->FirstChildElement("Sound");
+	if (pTexture)
+	{
+		m_audioResource = pTexture->FirstChild()->Value();
+	}
+
+	TiXmlElement* pLooping = pData->FirstChildElement("Looping");
+	if (pLooping)
+	{
+		std::string value = pLooping->FirstChild()->Value();
+		m_looping = (value == "0") ? false : true;
+	}
+
+	TiXmlElement* pFadeIn = pData->FirstChildElement("FadeIn");
+	if (pFadeIn)
+	{
+		std::string value = pFadeIn->FirstChild()->Value();
+		m_fadeInTime = (float)atof(value.c_str());
+	}
+
+	TiXmlElement* pVolume = pData->FirstChildElement("Volume");
+	if (pVolume)
+	{
+		std::string value = pVolume->FirstChild()->Value();
+		m_volume = atoi(value.c_str());
+	}
+
+	return true;
+}
+
+
+TiXmlElement* AudioComponent::VGenerateXml(void)
+{
+	TiXmlElement* pBaseElement = GCC_NEW TiXmlElement(VGetName());
+
+	TiXmlElement* pSoundNode = GCC_NEW TiXmlElement("Sound");
+	TiXmlText* pSoundText = GCC_NEW TiXmlText(m_audioResource.c_str());
+	pSoundNode->LinkEndChild(pSoundText);
+	pBaseElement->LinkEndChild(pSoundNode);
+
+	TiXmlElement* pLoopingNode = GCC_NEW TiXmlElement("Looping");
+	TiXmlText* pLoopingText = GCC_NEW TiXmlText(m_looping ? "1" : "0" );
+	pLoopingNode->LinkEndChild(pLoopingText);
+	pBaseElement->LinkEndChild(pLoopingNode);
+
+	TiXmlElement* pFadeInNode = GCC_NEW TiXmlElement("FadeIn");
+	TiXmlText* pFadeInText = GCC_NEW TiXmlText( ToStr(m_fadeInTime).c_str());
+	pFadeInNode->LinkEndChild(pFadeInText);
+	pBaseElement->LinkEndChild(pFadeInNode);
+
+	TiXmlElement* pVolumeNode = GCC_NEW TiXmlElement("Volume");
+	TiXmlText* pVolumeText = GCC_NEW TiXmlText( ToStr(m_volume).c_str());
+	pVolumeNode->LinkEndChild(pVolumeText);
+	pBaseElement->LinkEndChild(pVolumeNode);
+
+	return pBaseElement;
+}
+
+void AudioComponent::VPostInit()
+{
+	// TODO(munnellg) - implement
+}

+ 67 - 0
Source/GCC4/Actors/AudioComponent.h

@@ -0,0 +1,67 @@
+#pragma once
+//========================================================================
+// AudioComponent.h - A component for attaching sounds to an actor
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "ActorComponent.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+// AudioComponent class.
+// [rez] This component was never directly described anywhere in the book but it's used to allow actors to trigger 
+// sound effects.
+//---------------------------------------------------------------------------------------------------------------------
+class AudioComponent : public ActorComponent
+{
+	std::string m_audioResource;
+	bool m_looping;
+	float m_fadeInTime;
+	int m_volume;
+
+public:
+	static const char *g_Name;
+	virtual const char *VGetName() const { return g_Name; }
+
+	bool Start();
+
+	AudioComponent(void);
+
+	virtual TiXmlElement* VGenerateXml(void);
+
+	// ActorComponent interface
+	virtual bool VInit(TiXmlElement* pData) override;
+	virtual void VPostInit(void) override;
+};

+ 200 - 0
Source/GCC4/Actors/BaseScriptComponent.cpp

@@ -0,0 +1,200 @@
+//========================================================================
+// BaseScriptComponent.cpp - Component for exposing actors to Lua
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+#include "BaseScriptComponent.h"
+#include "../LUAScripting/LuaStateManager.h"
+
+// This is the name of the metatable where all the function definitions exported to Lua will live.
+static const char* METATABLE_NAME = "BaseScriptComponentMetaTable";
+const char* BaseScriptComponent::g_Name = "BaseScriptComponent";
+
+BaseScriptComponent::BaseScriptComponent(void)
+{
+	m_scriptObject = sol::object();
+	m_scriptDestructor = sol::nil;
+}
+
+BaseScriptComponent::~BaseScriptComponent(void)
+{
+	// call the script destructor if there is one
+	if (m_scriptDestructor.valid())
+	{
+		m_scriptDestructor(m_scriptObject);
+	}
+
+	// clear out the script object
+	m_scriptObject = sol::object();
+
+	// if we were given a path for this script object, set it to nil
+	if (!m_scriptObjectName.empty())
+	{
+		m_scriptObjectName += " = nil;";
+		LuaStateManager::Get()->VExecuteString(m_scriptObjectName.c_str());
+	}
+}
+
+bool BaseScriptComponent::VInit(TiXmlElement* pData)
+{
+	LuaStateManager* pStateMgr = LuaStateManager::Get();
+	GCC_ASSERT(pStateMgr);
+
+	sol::state_view lua = pStateMgr->GetLuaState();
+	sol::global_table global_table = pStateMgr->GetGlobalVars();
+
+	// load the <ScriptObject> tag and validate it
+	TiXmlElement* pScriptObjectElement = pData->FirstChildElement("ScriptObject");
+	if (!pScriptObjectElement)
+	{
+		GCC_ERROR("No <ScriptObject> tag in XML. This won't be a very useful script component.");
+		return true; // technically it succeeded even though it won't be accessible
+	}
+
+	// read all the attribute
+	const char* temp = NULL;
+	temp = pScriptObjectElement->Attribute("var");
+	if (temp)
+		m_scriptObjectName = temp;
+
+	temp = pScriptObjectElement->Attribute("constructor");
+	if (temp)
+		m_constructorName = temp;
+
+	temp = pScriptObjectElement->Attribute("destructor");
+	if (temp)
+		m_destructorName = temp;
+
+    // Having a var attribute will export the instance of this object to that name.
+	if (!m_scriptObjectName.empty())
+	{
+		m_scriptObject = pStateMgr->CreatePath(m_scriptObjectName.c_str());
+
+		if (m_scriptObject != sol::nil)
+		{
+			CreateScriptObject();
+		}
+	}
+
+	// The scriptConstructor attribute will also cause a Lua object to be created if one wasn't created in 
+    // the previous step.  The scriptConstructor string is treated as a function of the form f(scriptObject) 
+    // and is called.
+	if (!m_constructorName.empty())
+	{
+		m_scriptConstructor = global_table[m_constructorName.c_str()];
+		if (m_scriptConstructor.valid())
+		{
+			// m_scriptObject could be nil if there was no scriptObject attribute.  If this is the case, 
+            // the Lua object is created here.
+            if (m_scriptObject == sol::nil)
+            {
+            	m_scriptObject = lua.create_table();
+            	CreateScriptObject();
+            }
+		}
+	}
+
+	// The scriptDestructor attribute is treated as a function in the form of f(scriptObject) and is called
+    // when the C++ ScriptObject instance is destroyed.
+	if (!m_destructorName.empty())
+	{
+		m_scriptDestructor = global_table[m_destructorName];
+	}
+
+	return true;
+}
+
+void BaseScriptComponent::VPostInit(void)
+{
+	// call the script constructor if one exists
+	if (m_scriptConstructor.valid())
+	{
+		sol::protected_function_result result = m_scriptConstructor(m_scriptObject);
+
+		if (!result.valid())
+		{
+			sol::error err = result;
+			GCC_ERROR(std::string("Script constructor failed: ") + err.what());
+		}
+	}
+}
+
+TiXmlElement* BaseScriptComponent::VGenerateXml(void)
+{
+	TiXmlElement* pBaseElement = GCC_NEW TiXmlElement(VGetName());
+
+	// ScriptObject
+	TiXmlElement* pScriptObjectElement = GCC_NEW TiXmlElement("ScriptObject");
+	if (!m_scriptObjectName.empty())
+		pScriptObjectElement->SetAttribute("var", m_scriptObjectName.c_str());
+	if (!m_constructorName.empty())
+		pScriptObjectElement->SetAttribute("constructor", m_constructorName.c_str());
+	if (!m_destructorName.empty())
+		pScriptObjectElement->SetAttribute("destructor", m_destructorName.c_str());
+	pBaseElement->LinkEndChild(pScriptObjectElement);
+
+	return pBaseElement;
+}
+
+void BaseScriptComponent::CreateScriptObject(void)
+{
+	sol::state_view lua = LuaStateManager::Get()->GetLuaState();
+
+	m_scriptObject = sol::make_object(lua, this);
+}
+
+void BaseScriptComponent::RegisterScriptFunctions(void)
+{
+	// create the metatable
+	sol::state_view lua = LuaStateManager::Get()->GetLuaState();
+
+	lua.new_usertype<BaseScriptComponent>(METATABLE_NAME,
+		"GetActorId",				&BaseScriptComponent::GetActorId//,
+		// "GetPos",					&BaseScriptComponent::GetActorId,
+		// "SetPos",					&BaseScriptComponent::GetActorId,
+		// "GetLookAt",				&BaseScriptComponent::GetActorId,
+		// "GetYOrientationRadians",	&BaseScriptComponent::GetActorId,
+		// "RotateY", 					&BaseScriptComponent::GetActorId,
+		// "Stop", 					&BaseScriptComponent::GetActorId,
+		// "SetPosition", 				&BaseScriptComponent::GetActorId,
+	);
+}
+
+ActorId BaseScriptComponent::GetActorId(void)
+{
+	return m_pOwner->GetId();
+}

+ 74 - 0
Source/GCC4/Actors/BaseScriptComponent.h

@@ -0,0 +1,74 @@
+#pragma once
+//========================================================================
+// BaseScriptComponent.h - Component for exposing actors to Lua
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include"ScriptComponentInterface.h"
+#include <sol/sol.hpp>
+
+//---------------------------------------------------------------------------------------------------------------------
+// BaseScriptComponent class
+// Chapter 12, page 337
+//---------------------------------------------------------------------------------------------------------------------
+class BaseScriptComponent : public ScriptComponentInterface
+{
+	std::string m_scriptObjectName;
+	std::string m_constructorName;
+	std::string m_destructorName;
+
+	sol::object m_scriptObject;
+	sol::protected_function m_scriptConstructor;
+	sol::function m_scriptDestructor;
+
+public:
+	static const char* g_Name;
+	virtual const char* VGetName() const { return g_Name; }
+	
+	BaseScriptComponent(void);
+	~BaseScriptComponent(void);
+	virtual bool VInit(TiXmlElement* pData);
+	virtual void VPostInit(void);
+	virtual TiXmlElement* VGenerateXml(void);
+
+	static void RegisterScriptFunctions(void);
+
+private:
+	void CreateScriptObject(void);
+
+	// component script functions
+	ActorId GetActorId(void);
+};

+ 323 - 0
Source/GCC4/Actors/RenderComponent.cpp

@@ -0,0 +1,323 @@
+#pragma once
+//========================================================================
+// RenderComponent.cpp : classes that define renderable components of actors like Meshes, Skyboxes, Lights, etc.
+// Author: David "Rez" Graham
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+
+#include "../Graphics3D/Mesh.h"
+#include "../Graphics3D/Sky.h"
+
+#include "../EventManager/Events.h"
+#include "RenderComponent.h"
+#include "TransformComponent.h"
+
+// const char* MeshRenderComponent::g_Name = "MeshRenderComponent";
+// const char* SphereRenderComponent::g_Name = "SphereRenderComponent";
+const char* TeapotRenderComponent::g_Name = "TeapotRenderComponent";
+const char* GridRenderComponent::g_Name = "GridRenderComponent";
+const char* LightRenderComponent::g_Name = "LightRenderComponent";
+const char* SkyRenderComponent::g_Name = "SkyRenderComponent";
+
+//---------------------------------------------------------------------------------------------------------------------
+// RenderComponent
+//---------------------------------------------------------------------------------------------------------------------
+bool BaseRenderComponent::VInit(TiXmlElement* pData)
+{
+	// color
+	TiXmlElement* pColorNode = pData->FirstChildElement("Color");
+	if (pColorNode)
+		m_color = LoadColor(pColorNode);
+
+	return VDelegateInit(pData);
+}
+
+void BaseRenderComponent::VPostInit(void)
+{
+	std::shared_ptr<SceneNode> pSceneNode(VGetSceneNode());
+	std::shared_ptr<EvtData_New_Render_Component> pEvent(GCC_NEW EvtData_New_Render_Component(m_pOwner->GetId(), pSceneNode));
+	IEventManager::Get()->VTriggerEvent(pEvent);
+}
+
+void BaseRenderComponent::VOnChanged(void)
+{
+	std::shared_ptr<EvtData_Modified_Render_Component> pEvent(GCC_NEW EvtData_Modified_Render_Component(m_pOwner->GetId()));
+	IEventManager::Get()->VTriggerEvent(pEvent);
+}
+
+
+TiXmlElement* BaseRenderComponent::VGenerateXml(void)
+{
+	TiXmlElement* pBaseElement = VCreateBaseElement();
+
+	// color
+	TiXmlElement* pColor = GCC_NEW TiXmlElement("Color");
+	pColor->SetAttribute("r", ToStr(m_color.r).c_str());
+	pColor->SetAttribute("g", ToStr(m_color.g).c_str());
+	pColor->SetAttribute("b", ToStr(m_color.b).c_str());
+	pColor->SetAttribute("a", ToStr(m_color.a).c_str());
+	pBaseElement->LinkEndChild(pColor);
+
+	// create XML for inherited classes
+	VCreateInheritedXmlElements(pBaseElement);
+
+	return pBaseElement;
+}
+
+std::shared_ptr<SceneNode> BaseRenderComponent::VGetSceneNode(void)
+{
+    if (!m_pSceneNode)
+        m_pSceneNode = VCreateSceneNode();
+    return m_pSceneNode;
+}
+
+Color BaseRenderComponent::LoadColor(TiXmlElement* pData)
+{
+	Color color;
+
+    double r = 1.0;
+    double g = 1.0;
+    double b = 1.0;
+    double a = 1.0;
+
+    pData->Attribute("r", &r);
+    pData->Attribute("g", &g);
+    pData->Attribute("b", &b);
+    pData->Attribute("a", &a);
+
+    color.r = (float)r;
+    color.g = (float)g;
+    color.b = (float)b;
+    color.a = (float)a;
+
+	return color;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// TeapotRenderComponent
+//---------------------------------------------------------------------------------------------------------------------
+std::shared_ptr<SceneNode> TeapotRenderComponent::VCreateSceneNode(void)
+{
+    // get the transform component
+    std::shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name));
+    if (pTransformComponent)
+    {
+        WeakBaseRenderComponentPtr weakThis(this);
+        glm::mat4 rot90 = geometry::BuildRotationY(GCC_PI/2.0f);
+        std::shared_ptr<SceneNode> parent(GCC_NEW SceneNode(m_pOwner->GetId(), weakThis, RenderPass_Actor, pTransformComponent->GetTransform()));
+        std::shared_ptr<SceneNode> teapot(GCC_NEW OpenGLTeapotMeshNode(INVALID_ACTOR_ID, weakThis, RenderPass_Actor, rot90));
+        parent->VAddChild(teapot);
+        return parent;
+    }
+
+    return std::shared_ptr<SceneNode>();
+}
+
+void TeapotRenderComponent::VCreateInheritedXmlElements(TiXmlElement *)
+{
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+// GridRenderComponent
+//---------------------------------------------------------------------------------------------------------------------
+GridRenderComponent::GridRenderComponent(void)
+{
+    m_textureResource = "";
+    m_squares = 0;
+}
+
+bool GridRenderComponent::VDelegateInit(TiXmlElement* pData)
+{
+    TiXmlElement* pTexture = pData->FirstChildElement("Texture");
+    if (pTexture)
+    {
+        m_textureResource = pTexture->FirstChild()->Value();
+    }
+
+    TiXmlElement* pDivision = pData->FirstChildElement("Division");
+    if (pDivision)
+    {
+        m_squares = atoi(pDivision->FirstChild()->Value());
+    }
+
+    return true;
+}
+
+std::shared_ptr<SceneNode> GridRenderComponent::VCreateSceneNode(void)
+{
+    std::shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name));
+    if (pTransformComponent)
+    {
+        WeakBaseRenderComponentPtr weakThis(this);
+
+        return std::shared_ptr<SceneNode>(GCC_NEW OpenGLGrid(m_pOwner->GetId(), weakThis, pTransformComponent->GetTransform()));
+    }
+
+    return std::shared_ptr<SceneNode>();
+}
+
+void GridRenderComponent::VCreateInheritedXmlElements(TiXmlElement *pBaseElement)
+{
+    TiXmlElement* pTextureNode = GCC_NEW TiXmlElement("Texture");
+    TiXmlText* pTextureText = GCC_NEW TiXmlText(m_textureResource.c_str());
+    pTextureNode->LinkEndChild(pTextureText);
+    pBaseElement->LinkEndChild(pTextureNode);
+
+    TiXmlElement* pDivisionNode = GCC_NEW TiXmlElement("Division");
+    TiXmlText* pDivisionText = GCC_NEW TiXmlText(ToStr(m_squares).c_str());
+    pDivisionNode->LinkEndChild(pDivisionText);
+    pBaseElement->LinkEndChild(pDivisionNode);
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// LightRenderComponent
+//---------------------------------------------------------------------------------------------------------------------
+LightRenderComponent::LightRenderComponent(void)
+{
+}
+
+bool LightRenderComponent::VDelegateInit(TiXmlElement* pData)
+{
+    TiXmlElement* pLight = pData->FirstChildElement("Light");
+
+    double temp;
+    TiXmlElement* pAttenuationNode = NULL;
+    pAttenuationNode = pLight->FirstChildElement("Attenuation");
+    if (pAttenuationNode)
+    {
+        double temp;
+        pAttenuationNode->Attribute("const", &temp);
+        m_Props.m_Attenuation[0] = (float) temp;
+
+        pAttenuationNode->Attribute("linear", &temp);
+        m_Props.m_Attenuation[1] = (float) temp;
+
+        pAttenuationNode->Attribute("exp", &temp);
+        m_Props.m_Attenuation[2] = (float) temp;
+    }
+
+    TiXmlElement* pShapeNode = NULL;
+    pShapeNode = pLight->FirstChildElement("Shape");
+    if (pShapeNode)
+    {
+        pShapeNode->Attribute("range", &temp);
+        m_Props.m_Range = (float) temp;
+        pShapeNode->Attribute("falloff", &temp);
+        m_Props.m_Falloff = (float) temp;
+        pShapeNode->Attribute("theta", &temp);
+        m_Props.m_Theta = (float) temp;
+        pShapeNode->Attribute("phi", &temp);
+        m_Props.m_Phi = (float) temp;
+    }
+    return true;
+}
+
+std::shared_ptr<SceneNode> LightRenderComponent::VCreateSceneNode(void)
+{
+    std::shared_ptr<TransformComponent> pTransformComponent = MakeStrongPtr(m_pOwner->GetComponent<TransformComponent>(TransformComponent::g_Name));
+    if (pTransformComponent)
+    {
+        WeakBaseRenderComponentPtr weakThis(this);
+        return std::shared_ptr<SceneNode>(GCC_NEW OpenGLLightNode46(m_pOwner->GetId(), weakThis, m_Props, pTransformComponent->GetTransform()));
+    }
+    return std::shared_ptr<SceneNode>();
+}
+
+void LightRenderComponent::VCreateInheritedXmlElements(TiXmlElement *pBaseElement)
+{
+    TiXmlElement* pSceneNode = GCC_NEW TiXmlElement("Light");
+
+    // attenuation
+    TiXmlElement* pAttenuation = GCC_NEW TiXmlElement("Attenuation");
+    pAttenuation->SetAttribute("const", ToStr(m_Props.m_Attenuation[0]).c_str());
+    pAttenuation->SetAttribute("linear", ToStr(m_Props.m_Attenuation[1]).c_str());
+    pAttenuation->SetAttribute("exp", ToStr(m_Props.m_Attenuation[2]).c_str());
+    pSceneNode->LinkEndChild(pAttenuation);
+
+    // shape
+    TiXmlElement* pShape = GCC_NEW TiXmlElement("Shape");
+    pShape->SetAttribute("range", ToStr(m_Props.m_Range).c_str());
+    pShape->SetAttribute("falloff", ToStr(m_Props.m_Falloff).c_str());
+    pShape->SetAttribute("theta", ToStr(m_Props.m_Theta).c_str());
+    pShape->SetAttribute("phi", ToStr(m_Props.m_Phi).c_str());
+    pSceneNode->LinkEndChild(pShape);
+
+    pBaseElement->LinkEndChild(pSceneNode);
+
+}
+
+
+
+
+SkyRenderComponent::SkyRenderComponent(void)
+{
+}
+
+bool SkyRenderComponent::VDelegateInit(TiXmlElement* pData)
+{
+    TiXmlElement* pTexture = pData->FirstChildElement("Texture");
+    if (pTexture)
+    {
+    	m_textureResource = pTexture->FirstChild()->Value();
+    }
+	return true;
+}
+
+std::shared_ptr<SceneNode> SkyRenderComponent::VCreateSceneNode(void)
+{
+    std::shared_ptr<SkyNode> sky;
+    if (GameCodeApp::GetRendererImpl()==GameCodeApp::Renderer_OpenGL46)
+    {
+    	sky = std::shared_ptr<SkyNode>(GCC_NEW OpenGLSkyNode46(m_textureResource.c_str() ));
+    }
+    else
+    {
+    	GCC_ERROR("Unknown Renderer Implementation in VLoadGameDelegate");
+    }
+    return sky;
+}
+
+void SkyRenderComponent::VCreateInheritedXmlElements(TiXmlElement *pBaseElement)
+{
+    TiXmlElement* pTextureNode = GCC_NEW TiXmlElement("Texture");
+    TiXmlText* pTextureText = GCC_NEW TiXmlText(m_textureResource.c_str());
+    pTextureNode->LinkEndChild(pTextureText);
+    pBaseElement->LinkEndChild(pTextureNode);
+}

+ 157 - 0
Source/GCC4/Actors/RenderComponent.h

@@ -0,0 +1,157 @@
+#pragma once
+//========================================================================
+// RenderComponent.h : classes that define renderable components of actors like Meshes, Skyboxes, Lights, etc.
+// Author: David "Rez" Graham
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "RenderComponentInterface.h"
+#include "../Graphics3D/SceneNodes.h"
+#include "../Graphics3D/Lights.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+// RenderComponent base class.  This class does most of the work except actually creating the scene, which is 
+// delegated to the subclass through a factory method:
+// http://en.wikipedia.org/wiki/Factory_method_pattern
+//---------------------------------------------------------------------------------------------------------------------
+class BaseRenderComponent : public RenderComponentInterface
+{
+protected:
+	Color m_color;
+	std::shared_ptr<SceneNode> m_pSceneNode;
+
+public:
+	virtual bool VInit(TiXmlElement* pData) override;
+	virtual void VPostInit(void) override;
+	virtual void VOnChanged(void) override;
+	virtual TiXmlElement* VGenerateXml(void) override;
+	const Color GetColor() const { return m_color; }
+
+protected:
+	// loads the SceneNode specific data (represented in the <SceneNode> tag)
+	virtual bool VDelegateInit(TiXmlElement* pData) { return true; }
+	virtual std::shared_ptr<SceneNode> VCreateSceneNode(void) = 0;  // factory method to create the appropriate scene node
+	Color LoadColor(TiXmlElement* pData);
+
+	// editor stuff
+	virtual TiXmlElement* VCreateBaseElement(void) { return GCC_NEW TiXmlElement(VGetName()); }
+	virtual void VCreateInheritedXmlElements(TiXmlElement* pBaseElement) = 0;
+
+private:
+	virtual std::shared_ptr<SceneNode> VGetSceneNode(void) override;
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// Teapots, which are the main characters in the game.  DirectX actually has a function that generates a teapot Mesh
+// so we might as well use it.  We're game programmers, not artists.  ;)
+//---------------------------------------------------------------------------------------------------------------------
+class TeapotRenderComponent : public BaseRenderComponent
+{
+public:
+	static const char *g_Name;
+	virtual const char *VGetName() const { return g_Name; }
+
+protected:
+	virtual std::shared_ptr<SceneNode> VCreateSceneNode(void) override;  // factory method to create the appropriate scene node
+
+	// editor stuff
+	virtual void VCreateInheritedXmlElements(TiXmlElement* pBaseElement);
+};
+
+//---------------------------------------------------------------------------------------------------------------------
+// Grids, which represent the world
+//---------------------------------------------------------------------------------------------------------------------
+class GridRenderComponent : public BaseRenderComponent
+{
+	std::string m_textureResource;
+	int m_squares;
+
+public:
+	static const char *g_Name;
+	virtual const char *VGetName() const { return g_Name; }
+
+	GridRenderComponent(void);
+	const char* GetTextureResource() { return m_textureResource.c_str(); }
+	const int GetDivision() { return m_squares; }
+
+protected:
+	virtual bool VDelegateInit(TiXmlElement* pData) override;
+	virtual std::shared_ptr<SceneNode> VCreateSceneNode(void) override;  // factory method to create the appropriate scene node
+
+	// editor stuff
+	virtual void VCreateInheritedXmlElements(TiXmlElement* pBaseElement);
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// Lights
+//---------------------------------------------------------------------------------------------------------------------
+class LightRenderComponent : public BaseRenderComponent
+{
+	LightProperties m_Props;
+
+public:
+	static const char *g_Name;
+	virtual const char *VGetName() const { return g_Name; }
+
+	LightRenderComponent(void);
+
+protected:
+	virtual bool VDelegateInit(TiXmlElement* pData) override;
+	virtual std::shared_ptr<SceneNode> VCreateSceneNode(void) override; // factory method to create the appropriate scene node
+
+	// editor stuff
+	virtual void VCreateInheritedXmlElements(TiXmlElement* pBaseElement);
+};
+
+class SkyRenderComponent : public BaseRenderComponent
+{
+	std::string m_textureResource;
+
+public:
+	static const char *g_Name;
+	virtual const char *VGetName() const { return g_Name; }
+
+	SkyRenderComponent(void);
+
+protected:
+	virtual bool VDelegateInit(TiXmlElement* pData) override;
+	virtual std::shared_ptr<SceneNode> VCreateSceneNode(void) override;  // factory method to create the appropriate scene node
+
+	// editor stuff
+	virtual void VCreateInheritedXmlElements(TiXmlElement* pBaseElement);
+};

+ 50 - 0
Source/GCC4/Actors/RenderComponentInterface.h

@@ -0,0 +1,50 @@
+#pragma once
+//========================================================================
+// RenderComponentInterface.h - Interface for render components
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "ActorComponent.h"
+#include "../Graphics3D/SceneNodes.h"
+
+class RenderComponentInterface : public ActorComponent
+{
+public:
+//    virtual ComponentId VGetComponentId(void) const override { return COMPONENT_ID; }
+
+    // RenderComponentInterface
+    virtual std::shared_ptr<SceneNode> VGetSceneNode(void) = 0;
+};

+ 53 - 0
Source/GCC4/Actors/ScriptComponentInterface.h

@@ -0,0 +1,53 @@
+#pragma once
+//========================================================================
+// ScriptComponentInterface.h - Interface for script components
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "ActorComponent.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+// This component is essentially a placeholder for the script representation of the entity.  The engine doesn't do 
+// much (if anything) with it, hence the lack of interface.
+//---------------------------------------------------------------------------------------------------------------------
+class ScriptComponentInterface : public ActorComponent
+{
+public:
+//    static ComponentId COMPONENT_ID;
+//    virtual ComponentId VGetComponentId(void) const { return COMPONENT_ID; }
+};
+
+

+ 122 - 0
Source/GCC4/Actors/TransformComponent.cpp

@@ -0,0 +1,122 @@
+//========================================================================
+// TransformComponent.cpp - Component for managing transforms on actors
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+#include "TransformComponent.h"
+#include "../Graphics3D/Geometry.h"
+#include "../Utilities/String.h"
+
+#include <glm/gtx/string_cast.hpp>
+
+
+const char* TransformComponent::g_Name = "TransformComponent";
+
+bool TransformComponent::VInit(TiXmlElement* pData)
+{
+	GCC_ASSERT(pData);
+
+	// [mrmike] - this was changed post-press - because changes to the TransformComponents can come in partial definitions,
+	//            such as from the editor, its better to grab the current values rather than clear them out.
+
+	// glm::vec3 yawPitchRoll = m_transform.GetYawPitchRoll();
+	// yawPitchRoll.x = glm::degrees(yawPitchRoll.x);
+	// yawPitchRoll.y = glm::degrees(yawPitchRoll.y);
+	// yawPitchRoll.z = glm::degrees(yawPitchRoll.z);
+	glm::vec3 yawPitchRoll;
+	glm::vec3 position = geometry::GetPosition(m_transform);
+
+	TiXmlElement* pPositionElement = pData->FirstChildElement("Position");
+	if (pPositionElement)
+	{
+		double x = 0.0;
+		double y = 0.0;
+		double z = 0.0;
+		pPositionElement->Attribute("x", &x);
+		pPositionElement->Attribute("y", &y);
+		pPositionElement->Attribute("z", &z);
+		position = glm::vec3(x, y, z);
+	}
+
+	TiXmlElement* pOrientationElement = pData->FirstChildElement("YawPitchRoll");
+	if (pOrientationElement)
+	{
+		double yaw = 0.0;
+		double pitch = 0.0;
+		double roll = 0.0;
+		pOrientationElement->Attribute("x", &yaw);
+		pOrientationElement->Attribute("y", &pitch);
+		pOrientationElement->Attribute("z", &roll);
+		yawPitchRoll = glm::vec3(yaw, pitch, roll);
+	}
+
+	glm::mat4 translation = geometry::BuildTranslation(position);
+	glm::mat4 rotation = geometry::BuildYawPitchRoll(
+		glm::radians(yawPitchRoll.x),
+		glm::radians(yawPitchRoll.y),
+		glm::radians(yawPitchRoll.z)
+	);
+
+	m_transform = rotation * translation;
+	
+	return true;
+}
+
+TiXmlElement* TransformComponent::VGenerateXml(void)
+{
+	TiXmlElement* pBaseElement = GCC_NEW TiXmlElement(VGetName());
+
+	// initial transform -> position
+	TiXmlElement *pPosition = GCC_NEW TiXmlElement("Position");
+	glm::vec3 pos(geometry::GetPosition(m_transform));
+	pPosition->SetAttribute("x", ToStr(pos.x).c_str());
+	pPosition->SetAttribute("y", ToStr(pos.y).c_str());
+	pPosition->SetAttribute("z", ToStr(pos.z).c_str());
+
+	// initial transform -> LookAt
+	TiXmlElement* pDirection = GCC_NEW TiXmlElement("YawPitchRoll");
+	glm::vec3 orient(geometry::GetYawPitchRoll(m_transform));
+	orient.x = glm::degrees(orient.x);
+	orient.y = glm::degrees(orient.y);
+	orient.z = glm::degrees(orient.z);
+	pDirection->SetAttribute("x", ToStr(orient.x).c_str());
+	pDirection->SetAttribute("y", ToStr(orient.y).c_str());
+	pDirection->SetAttribute("z", ToStr(orient.z).c_str());
+	pBaseElement->LinkEndChild(pDirection);
+
+	return pBaseElement;
+}

+ 63 - 0
Source/GCC4/Actors/TransformComponent.h

@@ -0,0 +1,63 @@
+#pragma once
+//========================================================================
+// TransformComponent.h - Component for managing transforms on actors
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "ActorComponent.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+// This component implementation is a very simple representation of the physical aspect of an actor.  It just defines 
+// the transform and doesn't register with the physics system at all.
+//---------------------------------------------------------------------------------------------------------------------
+class TransformComponent : public ActorComponent
+{
+	glm::mat4 m_transform;
+public:
+	static const char* g_Name;
+	virtual const char* VGetName() const { return g_Name; }
+
+	TransformComponent(void) : m_transform(glm::mat4(1.0)) { }
+	virtual bool VInit(TiXmlElement* pData) override;
+	virtual TiXmlElement* VGenerateXml(void) override;
+
+	// transform functions
+	glm::mat4 GetTransform(void) const { return m_transform; }
+	void SetTransform(const glm::mat4& newTransform) { m_transform = newTransform; }
+	glm::vec3 GetPosition(void) const { return geometry::GetPosition(m_transform); }
+	void SetPosition(const glm::vec3& pos) { geometry::SetPosition(m_transform, pos); }
+	glm::vec3 GetLookAt(void) const { return geometry::GetDirection(m_transform); }
+};

+ 387 - 0
Source/GCC4/Debugging/Logger.cpp

@@ -0,0 +1,387 @@
+//========================================================================
+// Logger.cpp : 
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+#include "../Unix/GameCodeStd.h"
+#include "Logger.h"
+#include "../Utilities/Dialogs.h"
+
+#include "../Multicore/CriticalSection.h"
+
+using std::string;
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// Some constants
+//------------------------------------------------------------------------------------------------------------------------------------
+
+// the log filename
+static const char* ERRORLOG_FILENAME = "error.log";
+
+#define NDEBUG 1
+
+// default display flags
+#ifdef _DEBUG
+	const unsigned char ERRORFLAG_DEFAULT =		LOGFLAG_WRITE_TO_DEBUGGER;
+	const unsigned char WARNINGFLAG_DEFAULT =	LOGFLAG_WRITE_TO_DEBUGGER;
+	const unsigned char LOGFLAG_DEFAULT =		LOGFLAG_WRITE_TO_DEBUGGER;
+#elif NDEBUG
+	const unsigned char ERRORFLAG_DEFAULT =		(LOGFLAG_WRITE_TO_DEBUGGER | LOGFLAG_WRITE_TO_LOG_FILE);
+	const unsigned char WARNINGFLAG_DEFAULT =	(LOGFLAG_WRITE_TO_DEBUGGER | LOGFLAG_WRITE_TO_LOG_FILE);
+	const unsigned char LOGFLAG_DEFAULT =		(LOGFLAG_WRITE_TO_DEBUGGER | LOGFLAG_WRITE_TO_LOG_FILE);
+#else
+	const unsigned char ERRORFLAG_DEFAULT =		0;
+	const unsigned char WARNINGFLAG_DEFAULT =	0;
+	const unsigned char LOGFLAG_DEFAULT =		0;
+#endif
+
+// singleton
+class LogMgr;
+static LogMgr* s_pLogMgr = NULL;
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// LogMgr class
+//------------------------------------------------------------------------------------------------------------------------------------
+class LogMgr
+{
+public:
+	enum ErrorDialogResult
+	{
+		LOGMGR_ERROR_ABORT,
+		LOGMGR_ERROR_RETRY,
+		LOGMGR_ERROR_IGNORE
+	};
+
+	typedef std::map<string, unsigned char> Tags;
+	typedef std::list<Logger::ErrorMessenger*> ErrorMessengerList;
+
+	Tags m_tags;
+	ErrorMessengerList m_errorMessengers;
+
+	// thread safety
+	CriticalSection m_tagCriticalSection;
+	CriticalSection m_messengerCriticalSection;
+
+public:
+	// construction
+	LogMgr(void);
+	~LogMgr(void);
+	void Init(const char* loggingConfigFilename);
+
+	// logs
+	void Log(const string& tag, const string& message, const char* funcName, const char* sourceFile, unsigned int lineNum);
+	void SetDisplayFlags(const std::string& tag, unsigned char flags);
+
+	// error messengers
+	void AddErrorMessenger(Logger::ErrorMessenger* pMessenger);
+	LogMgr::ErrorDialogResult Error(const std::string& errorMessage, bool isFatal, const char* funcName, const char* sourceFile, unsigned int lineNum);
+
+private:
+	// log helpers
+	void OutputFinalBufferToLogs(const string& finalBuffer, unsigned char flags);
+	void WriteToLogFile(const string& data);
+	void GetOutputBuffer(std::string& outOutputBuffer, const string& tag, const string& message, const char* funcName, const char* sourceFile, unsigned int lineNum);
+};
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// Constructor
+//------------------------------------------------------------------------------------------------------------------------------------
+LogMgr::LogMgr(void)
+{
+	// set up the default log tags
+	SetDisplayFlags("ERROR", ERRORFLAG_DEFAULT);
+	SetDisplayFlags("WARNING", WARNINGFLAG_DEFAULT);
+	SetDisplayFlags("INFO", LOGFLAG_DEFAULT);
+}
+
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// Destructor
+//------------------------------------------------------------------------------------------------------------------------------------
+LogMgr::~LogMgr(void)
+{
+	m_messengerCriticalSection.Lock();
+	for (auto it = m_errorMessengers.begin(); it != m_errorMessengers.end(); ++it)
+	{
+		Logger::ErrorMessenger* pMessenger = (*it);
+		delete pMessenger;
+	}
+	m_errorMessengers.clear();
+	m_messengerCriticalSection.Unlock();
+}
+
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// Initializes the logger.
+//------------------------------------------------------------------------------------------------------------------------------------
+void LogMgr::Init(const char* loggingConfigFilename)
+{
+	if (loggingConfigFilename)
+	{
+		TiXmlDocument loggingConfigFile(loggingConfigFilename);
+		if (loggingConfigFile.LoadFile())
+		{
+			TiXmlElement* pRoot = loggingConfigFile.RootElement();
+			if (!pRoot)
+				return;
+
+			// Loop through each child element and load the component
+			for (TiXmlElement* pNode = pRoot->FirstChildElement(); pNode; pNode = pNode->NextSiblingElement())
+			{
+				unsigned char flags = 0;
+				std::string tag(pNode->Attribute("tag"));
+
+				int debugger = 0;
+				pNode->Attribute("debugger", &debugger);
+				if (debugger)
+					flags |= LOGFLAG_WRITE_TO_DEBUGGER;
+
+				int logfile = 0;
+				pNode->Attribute("file", &logfile);
+				if (logfile)
+					flags |= LOGFLAG_WRITE_TO_LOG_FILE;
+
+				SetDisplayFlags(tag, flags);
+			}
+		}
+	}
+}
+
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// This function builds up the log string and outputs it to various places based on the display flags (m_displayFlags).
+//------------------------------------------------------------------------------------------------------------------------------------
+void LogMgr::Log(const string& tag, const string& message, const char* funcName, const char* sourceFile, unsigned int lineNum)
+{
+	m_tagCriticalSection.Lock();
+	Tags::iterator findIt = m_tags.find(tag);
+	if (findIt != m_tags.end())
+	{
+		m_tagCriticalSection.Unlock();
+
+		string buffer;
+		GetOutputBuffer(buffer, tag, message, funcName, sourceFile, lineNum);
+		OutputFinalBufferToLogs(buffer, findIt->second);
+	}
+	else
+	{
+		// Critical section is exited in the if statement above, so we need to exit it here if that didn't
+		// get executed
+		m_tagCriticalSection.Unlock();
+	}
+} // end LogMgr::Log()
+
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// Sets one or more display flags
+//------------------------------------------------------------------------------------------------------------------------------------
+void LogMgr::SetDisplayFlags(const std::string& tag, unsigned char flags)
+{
+	m_tagCriticalSection.Lock();
+	if (flags != 0)
+	{
+		Tags::iterator findIt = m_tags.find(tag);
+		if (findIt == m_tags.end())
+			m_tags.insert(std::make_pair(tag, flags));
+		else
+			findIt->second = flags;
+	}
+	else
+	{
+		m_tags.erase(tag);
+	}
+	m_tagCriticalSection.Unlock();
+}
+
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// Adds an error messenger to the list
+//------------------------------------------------------------------------------------------------------------------------------------
+void LogMgr::AddErrorMessenger(Logger::ErrorMessenger* pMessenger)
+{
+	m_messengerCriticalSection.Lock();
+	m_errorMessengers.push_back(pMessenger);
+	m_messengerCriticalSection.Unlock();
+}
+
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// Helper for ErrorMessenger.
+//------------------------------------------------------------------------------------------------------------------------------------
+LogMgr::ErrorDialogResult LogMgr::Error(const std::string& errorMessage, bool isFatal, const char* funcName, const char* sourceFile, unsigned int lineNum)
+{
+	string tag = ((isFatal) ? ("FATAL") : ("ERROR"));
+
+	// buffer for our final output string
+	string buffer;
+	GetOutputBuffer(buffer, tag, errorMessage, funcName, sourceFile, lineNum);
+
+	// write the final buffer to all the various logs
+	m_tagCriticalSection.Lock();
+	Tags::iterator findIt = m_tags.find(tag);
+	if (findIt != m_tags.end())
+		OutputFinalBufferToLogs(buffer, findIt->second);
+	m_tagCriticalSection.Unlock();
+
+	// show the dialog box
+	int result = MessageBox(NULL, buffer.c_str(), tag.c_str(), MB_ABORTRETRYIGNORE|MB_ICONERROR);
+
+	// act upon the choice
+	switch (result)
+	{
+		case IDIGNORE : return LogMgr::LOGMGR_ERROR_IGNORE;
+		case IDABORT  : /*__debugbreak(); */ return LogMgr::LOGMGR_ERROR_ABORT;  // assembly language instruction to break into the debugger
+		case IDRETRY :	return LogMgr::LOGMGR_ERROR_RETRY;
+		default :       return LogMgr::LOGMGR_ERROR_RETRY;
+	}
+}
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// This is a helper function that checks all the display flags and outputs the passed in finalBuffer to the appropriate places.
+// 
+// IMPORTANT: The two places this function is called from wrap the code in the tag critical section (m_pTagCriticalSection), 
+// so that makes this call thread safe.  If you call this from anywhere else, make sure you wrap it in that critical section.
+//------------------------------------------------------------------------------------------------------------------------------------
+void LogMgr::OutputFinalBufferToLogs(const string& finalBuffer, unsigned char flags)
+{
+	// Write the log to each display based on the display flags
+	if ((flags & LOGFLAG_WRITE_TO_LOG_FILE) > 0) // log file
+		WriteToLogFile(finalBuffer);
+	if ((flags & LOGFLAG_WRITE_TO_DEBUGGER) > 0) // log file
+		fputs(finalBuffer.c_str(), stderr);
+		// ::OutputDebugStringA(finalBuffer.c_str());
+}
+
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// This is a helper function that writes the data string to the log file.
+//------------------------------------------------------------------------------------------------------------------------------------
+void LogMgr::WriteToLogFile(const string& data)
+{
+	FILE* pLogFile = NULL;
+	pLogFile = fopen(ERRORLOG_FILENAME, "a+");
+	if (!pLogFile)
+		return;
+
+	fputs(data.c_str(), pLogFile);
+
+	fclose(pLogFile);
+}
+
+//------------------------------------------------------------------------------------------------------------------------------------
+// Fills outOutputBuffer with the find error string.
+//------------------------------------------------------------------------------------------------------------------------------------
+void LogMgr::GetOutputBuffer(std::string& outOutputBuffer, const string& tag, const string& message, const char* funcName, const char* sourceFile, unsigned int lineNum)
+{
+	if (!tag.empty())
+		outOutputBuffer = "[" + tag + "] " + message;
+	else
+		outOutputBuffer = message;
+
+	if (funcName != NULL)
+	{
+		outOutputBuffer += "\nFunction: ";
+		outOutputBuffer += funcName;
+	}
+	if (sourceFile != NULL)
+	{
+		outOutputBuffer += "\n";
+		outOutputBuffer += sourceFile;
+	}
+	if (lineNum != 0)
+	{
+		outOutputBuffer += "\nLine: ";
+		char lineNumBuffer[11];
+		memset(lineNumBuffer, 0, sizeof(char));
+		snprintf(lineNumBuffer, sizeof(lineNumBuffer), "%u", lineNum);
+		outOutputBuffer += lineNumBuffer;
+	}
+
+	outOutputBuffer += "\n";
+}
+
+
+//-----------------------------------------------------------------------------------------------------------------------
+// ErrorMessenger
+//-----------------------------------------------------------------------------------------------------------------------
+Logger::ErrorMessenger::ErrorMessenger(void)
+{
+	s_pLogMgr->AddErrorMessenger(this);
+	m_enabled = true;
+}
+
+void Logger::ErrorMessenger::Show(const std::string& errorMessage, bool isFatal, const char* funcName, const char* sourceFile, unsigned int lineNum)
+{
+	if (m_enabled)
+	{
+        if (s_pLogMgr->Error(errorMessage, isFatal, funcName, sourceFile, lineNum) == LogMgr::LOGMGR_ERROR_IGNORE)
+            m_enabled = false;
+	}
+}
+
+//-----------------------------------------------------------------------------------------------------------------------
+// C Interface
+//-----------------------------------------------------------------------------------------------------------------------
+
+namespace Logger {
+
+void Init(const char* loggingConfigFilename)
+{
+	if (!s_pLogMgr)
+	{
+		s_pLogMgr = GCC_NEW LogMgr;
+		s_pLogMgr->Init(loggingConfigFilename);
+	}
+}
+
+void Destroy(void)
+{
+	delete s_pLogMgr;
+	s_pLogMgr = NULL;
+}
+
+void Log(const string& tag, const string& message, const char* funcName, const char* sourceFile, unsigned int lineNum)
+{
+	GCC_ASSERT(s_pLogMgr);
+	s_pLogMgr->Log(tag, message, funcName, sourceFile, lineNum);
+}
+
+void SetDisplayFlags(const std::string& tag, unsigned char flags)
+{
+	GCC_ASSERT(s_pLogMgr);
+	s_pLogMgr->SetDisplayFlags(tag, flags);
+}
+
+} // end namespace Logger

+ 185 - 0
Source/GCC4/Debugging/Logger.h

@@ -0,0 +1,185 @@
+#pragma once
+//========================================================================
+// Logger.h : 
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+//---------------------------------------------------------------------------------------------------------------------
+// TYPICAL USAGE:
+// 
+// 1) Call the GCC_ASSERT() macro just like you would for _ASSERTE()
+//		Example -> GCC_ASSERT(ptr != NULL);
+// 2) Call the GCC_ERROR() macro to send out an error message
+//		Example -> GCC_ERROR("Something Blew Up!");
+//---------------------------------------------------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------------------------------------------------
+// LOGGING:
+// 
+// Calling  GCC_LOG("tag", "Log message") will print:
+//  [tag] Log Message
+// To enable these logs, you need to either manually call Logger::SetDisplayFlags() or set up a logging.xml file.
+// logging.xml should follow this form:
+// 
+//  <Logger>
+//      <Log tag="Actor" debugger="1" file="0"/>
+//  </Logger>
+// 
+// The above chunk will cause all logs sent with the "Actor" tag to be displayed in the debugger.  If you set file 
+// to 1 as well, it would log out to a file as well.  Don't check in logging.xml to SVN, it should be a local-only 
+// file.
+//---------------------------------------------------------------------------------------------------------------------
+
+#include <string>
+#include "../Unix/GameCodeStd.h"
+//---------------------------------------------------------------------------------------------------------------------
+// Constants
+//---------------------------------------------------------------------------------------------------------------------
+
+// display flags
+const unsigned char LOGFLAG_WRITE_TO_LOG_FILE =		1 << 0;
+const unsigned char LOGFLAG_WRITE_TO_DEBUGGER =		1 << 1;
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// This is the public Logger interface.  You must call Init() before any logging can take place and Destroy() when
+// you're done to clean it up.  Call SetDisplayFlags() to set the display flags for a particular logging tag.  By 
+// default, they are all off.  Although you can, you probably shouldn't call Log() directly.  Use the GCC_LOG() macro 
+// instead since it can be stripped out by the compiler for Release builds.
+//---------------------------------------------------------------------------------------------------------------------
+namespace Logger
+{
+	// This class is used by the debug macros and shouldn't be accessed externally.
+	class ErrorMessenger
+	{
+		bool m_enabled;
+	public:
+		ErrorMessenger(void);
+		void Show(const std::string& errorMessage, bool isFatal, const char* funcName, const char* sourceFile, unsigned int lineNum);
+	};
+
+	// construction; must be called at the beginning and end of the program
+	void Init(const char* loggingConfigFilename);
+	void Destroy(void);
+
+	// logging functions
+	void Log(const std::string& tag, const std::string& message, const char* funcName, const char* sourceFile, unsigned int lineNum);
+	void SetDisplayFlags(const std::string& tag, unsigned char flags);
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// Debug macros
+//---------------------------------------------------------------------------------------------------------------------
+
+// Fatal Errors are fatal and are always presented to the user.
+#define GCC_FATAL(str) \
+	do \
+	{ \
+		static Logger::ErrorMessenger* pErrorMessenger = GCC_NEW Logger::ErrorMessenger; \
+		std::string s((str)); \
+		pErrorMessenger->Show(s, true, __FUNCTION__, __FILE__, __LINE__); \
+	} \
+	while (0)\
+
+#if 1 //ndef NDEBUG
+
+// Errors are bad and potentially fatal.  They are presented as a dialog with Abort, Retry, and Ignore.  Abort will
+// break into the debugger, retry will continue the game, and ignore will continue the game and ignore every subsequent 
+// call to this specific error.  They are ignored completely in release mode.
+#define GCC_ERROR(str) \
+	do \
+	{ \
+		static Logger::ErrorMessenger* pErrorMessenger = GCC_NEW Logger::ErrorMessenger; \
+		std::string s((str)); \
+		pErrorMessenger->Show(s, false, __FUNCTION__, __FILE__, __LINE__); \
+	} \
+	while (0)\
+
+// Warnings are recoverable.  They are just logs with the "WARNING" tag that displays calling information.  The flags
+// are initially set to WARNINGFLAG_DEFAULT (defined in debugger.cpp), but they can be overridden normally.
+#define GCC_WARNING(str) \
+	do \
+	{ \
+		std::string s((str)); \
+		Logger::Log("WARNING", s, __FUNCTION__, __FILE__, __LINE__); \
+	}\
+	while (0)\
+
+// This is just a convenient macro for logging if you don't feel like dealing with tags.  It calls Log() with a tag
+// of "INFO".  The flags are initially set to LOGFLAG_DEFAULT (defined in debugger.cpp), but they can be overridden 
+// normally.
+#define GCC_INFO(str) \
+	do \
+	{ \
+		std::string s((str)); \
+		Logger::Log("INFO", s, NULL, NULL, 0); \
+	} \
+	while (0) \
+
+// This macro is used for logging and should be the preferred method of "printf debugging".  You can use any tag 
+// string you want, just make sure to enabled the ones you want somewhere in your initialization.
+#define GCC_LOG(tag, str) \
+	do \
+	{ \
+		std::string s((str)); \
+		Logger::Log(tag, s, NULL, NULL, 0); \
+	} \
+	while (0) \
+
+// This macro replaces GCC_ASSERT().
+#define GCC_ASSERT(expr) \
+	do \
+	{ \
+		if (!(expr)) \
+		{ \
+			static Logger::ErrorMessenger* pErrorMessenger = GCC_NEW Logger::ErrorMessenger; \
+			pErrorMessenger->Show(#expr, false, __FUNCTION__, __FILE__, __LINE__); \
+		} \
+	} \
+	while (0) \
+
+#else  // NDEBUG is defined
+
+// These are the release mode definitions for the macros above.  They are all defined in such a way as to be 
+// ignored completely by the compiler.
+#define GCC_ERROR(str) do { (void)sizeof(str); } while(0) 
+#define GCC_WARNING(str) do { (void)sizeof(str); } while(0) 
+#define GCC_INFO(str) do { (void)sizeof(str); } while(0) 
+#define GCC_LOG(tag, str) do { (void)sizeof(tag); (void)sizeof(str); } while(0) 
+#define GCC_ASSERT(expr) do { (void)sizeof(expr); } while(0) 
+
+#endif  // !defined NDEBUG

+ 72 - 0
Source/GCC4/EventManager/EventManager.cpp

@@ -0,0 +1,72 @@
+//========================================================================
+// EventManager.cpp : implements a multi-listener multi-sender event system
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+
+#include "../Unix/GameCodeStd.h"
+#include "EventManager.h"
+
+static IEventManager* g_pEventMgr = NULL;
+
+//GCC_MEMORY_WATCHER_DEFINITION(IEventData);
+
+IEventManager* IEventManager::Get(void)
+{
+	GCC_ASSERT(g_pEventMgr);
+	return g_pEventMgr;
+}
+
+IEventManager::IEventManager(const char* pName, bool setAsGlobal)
+{
+	if (setAsGlobal)
+    {
+        if (g_pEventMgr)
+        {
+            GCC_ERROR("Attempting to create two global event managers! The old one will be destroyed and overwritten with this one.");
+            delete g_pEventMgr;
+        }
+
+		g_pEventMgr = this;
+    }
+}
+
+IEventManager::~IEventManager(void)
+{
+	if (g_pEventMgr == this)
+		g_pEventMgr = NULL;
+}
+

+ 146 - 0
Source/GCC4/EventManager/EventManager.h

@@ -0,0 +1,146 @@
+#pragma once
+
+//========================================================================
+// EventManager.h : implements a multi-listener multi-sender event system
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include <strstream>
+#include <functional>
+#include <FastDelegate.h>
+
+//---------------------------------------------------------------------------------------------------------------------
+// Forward declaration & typedefs
+//---------------------------------------------------------------------------------------------------------------------
+class IEventData;
+
+typedef unsigned long EventType;
+typedef std::shared_ptr<IEventData> IEventDataPtr;
+typedef fastdelegate::FastDelegate1<IEventDataPtr> EventListenerDelegate;
+// typedef concurrent_queue<IEventDataPtr> ThreadSafeEventQueue;
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// IEventData                               - Chapter 11, page 310
+// Base type for event object hierarchy, may be used itself for simplest event notifications such as those that do 
+// not carry additional payload data. If any event needs to propagate with payload data it must be defined separately.
+//---------------------------------------------------------------------------------------------------------------------
+class IEventData 
+{
+public:
+	virtual ~IEventData(void) {}
+	virtual const EventType& VGetEventType(void) const = 0;
+	virtual float GetTimeStamp(void) const = 0;
+	virtual void VSerialize(std::ostrstream& out) const = 0;
+    virtual void VDeserialize(std::istrstream& in) = 0;
+	virtual IEventDataPtr VCopy(void) const = 0;
+    virtual const char* GetName(void) const = 0;
+
+    //GCC_MEMORY_WATCHER_DECLARATION();
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// class BaseEventData		- Chapter 11, page 311
+//---------------------------------------------------------------------------------------------------------------------
+class BaseEventData : public IEventData
+{
+    const float m_timeStamp;
+
+public:
+	explicit BaseEventData(const float timeStamp = 0.0f) : m_timeStamp(timeStamp) { }
+
+	// Returns the type of the event
+	virtual const EventType& VGetEventType(void) const = 0;
+
+	float GetTimeStamp(void) const { return m_timeStamp; }
+
+	// Serializing for network input / output
+	virtual void VSerialize(std::ostrstream &out) const	{ }
+    virtual void VDeserialize(std::istrstream& in) { }
+};
+
+//---------------------------------------------------------------------------------------------------------------------
+// IEventManager Description                        Chapter 11, page 314
+//
+// This is the object which maintains the list of registered events and their listeners.
+//
+// This is a many-to-many relationship, as both one listener can be configured to process multiple event types and 
+// of course multiple listeners can be registered to each event type.
+//
+// The interface to this construct uses smart pointer wrapped objects, the purpose being to ensure that no object 
+// that the registry is referring to is destroyed before it is removed from the registry AND to allow for the registry 
+// to be the only place where this list is kept ... the application code does not need to maintain a second list.
+//
+// Simply tearing down the registry (e.g.: destroying it) will automatically clean up all pointed-to objects (so long 
+// as there are no other outstanding references, of course).
+//---------------------------------------------------------------------------------------------------------------------
+class IEventManager
+{
+public:
+
+	enum eConstants { kINFINITE = 0xffffffff };
+	explicit IEventManager(const char* pName, bool setAsGlobal);
+	virtual ~IEventManager(void);
+
+    // Registers a delegate function that will get called when the event type is triggered.  Returns true if 
+    // successful, false if not.
+    virtual bool VAddListener(const EventListenerDelegate& eventDelegate, const EventType& type) = 0;
+
+	// Removes a delegate / event type pairing from the internal tables.  Returns false if the pairing was not found.
+	virtual bool VRemoveListener(const EventListenerDelegate& eventDelegate, const EventType& type) = 0;
+
+	// Fire off event NOW.  This bypasses the queue entirely and immediately calls all delegate functions registered 
+    // for the event.
+	virtual bool VTriggerEvent(const IEventDataPtr& pEvent) const = 0;
+
+	// Fire off event.  This uses the queue and will call the delegate function on the next call to VTick(), assuming
+    // there's enough time.
+	virtual bool VQueueEvent(const IEventDataPtr& pEvent) = 0;
+	// virtual bool VThreadSafeQueueEvent(const IEventDataPtr& pEvent) = 0;
+
+	// Allow for processing of any queued messages, optionally specify a processing time limit so that the event 
+    // processing does not take too long. Note the danger of using this artificial limiter is that all messages 
+    // may not in fact get processed.
+	//
+	// returns true if all messages ready for processing were completed, false otherwise (e.g. timeout )
+	virtual bool VUpdate(unsigned long maxMillis = kINFINITE) = 0;
+
+	// Getter for the main global event manager.  This is the event manager that is used by the majority of the 
+	// engine, though you are free to define your own as long as you instantiate it with setAsGlobal set to false.
+	// It is not valid to have more than one global event manager.
+	static IEventManager* Get(void);
+};

+ 249 - 0
Source/GCC4/EventManager/EventManagerImpl.cpp

@@ -0,0 +1,249 @@
+//========================================================================
+// EventManagerImpl.cpp : implementation side of the event system
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+#include "EventManagerImpl.h"
+#include "../Utilities/String.h"
+
+#include <SDL3/SDL.h>
+
+//---------------------------------------------------------------------------------------------------------------------
+// EventManager::EventManager
+//---------------------------------------------------------------------------------------------------------------------
+EventManager::EventManager(const char* pName, bool setAsGlobal)
+	: IEventManager(pName, setAsGlobal)
+{
+	m_activeQueue = 0;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// EventManager::~EventManager
+//---------------------------------------------------------------------------------------------------------------------
+EventManager::~EventManager()
+{
+	//
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// EventManager::VAddListener
+//---------------------------------------------------------------------------------------------------------------------
+bool EventManager::VAddListener(const EventListenerDelegate& eventDelegate, const EventType& type)
+{
+	GCC_LOG("Events", "Attempting to add delegate function for event type: " + ToStr(type, 16));
+
+	EventListenerList& eventListenerList = m_eventListeners[type]; // this will find or create the entry;
+	for (auto it = eventListenerList.begin(); it != eventListenerList.end(); ++it)
+	{
+		if (eventDelegate == (*it))
+		{
+			GCC_WARNING("Attempting to double-register a delegate");
+			return false;
+		}
+	}
+
+	eventListenerList.push_back(eventDelegate);
+	GCC_LOG("Events", "Successfully added delegate for event type: " + ToStr(type, 16));
+
+	return true;
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+// EventManager::VRemoveListener
+//---------------------------------------------------------------------------------------------------------------------
+bool EventManager::VRemoveListener(const EventListenerDelegate& eventDelegate, const EventType& type)
+{
+	GCC_LOG("Events", "Attempting to remove delegate function from event type: " + ToStr(type, 16));
+	bool success = false;
+
+	auto findIt = m_eventListeners.find(type);
+	if (findIt != m_eventListeners.end())
+	{
+		EventListenerList& listeners = findIt->second;
+		for (auto it = listeners.begin(); it != listeners.end(); ++it)
+		{
+			if (eventDelegate == (*it))
+			{
+				listeners.erase(it);
+				GCC_LOG("Events", "Successfully removed delegate function from event type: " + ToStr(type, 16));
+				success = true;
+				break;  // we don't need to continue because it should be impossible for the same delegate function to be registered for the same event more than once
+			}
+		}
+	}
+
+	return success;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// EventManager::VTrigger
+//---------------------------------------------------------------------------------------------------------------------
+bool EventManager::VTriggerEvent(const IEventDataPtr& pEvent) const
+{
+	GCC_LOG("Events", "Attempting to trigger event " + std::string(pEvent->GetName()));
+	bool processed = false;
+
+	auto findIt = m_eventListeners.find(pEvent->VGetEventType());
+	if (findIt != m_eventListeners.end())
+	{		
+		const EventListenerList& eventListenerList = findIt->second;
+		for (EventListenerList::const_iterator it = eventListenerList.begin(); it != eventListenerList.end(); ++it)
+		{
+			EventListenerDelegate listener = (*it);
+			GCC_LOG("Events", "Sending Event " + std::string(pEvent->GetName()) + " to delegate.");
+			listener(pEvent); // call the delegate
+			processed = true;
+		}
+	}
+	return processed;
+}
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// EventManager::VQueueEvent
+//---------------------------------------------------------------------------------------------------------------------
+bool EventManager::VQueueEvent(const IEventDataPtr& pEvent)
+{
+	GCC_ASSERT(m_activeQueue >= 0);
+	GCC_ASSERT(m_activeQueue < EVENTMANAGER_NUM_QUEUES);
+
+	// make sure the event is valid
+	if (!pEvent)
+	{
+		GCC_ERROR("Invalid event in VQueueEvent()");
+		return false;
+	}
+
+	GCC_LOG("Events", "Attempting to queue event: " + std::string(pEvent->GetName()));
+	auto findIt = m_eventListeners.find(pEvent->VGetEventType());
+	if (findIt != m_eventListeners.end())
+	{
+		m_queues[m_activeQueue].push_back(pEvent);
+		GCC_LOG("Events", "Successfully queued event: " + std::string(pEvent->GetName()));
+		return true;
+	}
+	else
+	{
+		GCC_LOG("Events", "Skipping event since there are no delegates registered to receive it: " + std::string(pEvent->GetName()));
+		return false;
+	}
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+// EventManager::VTick
+//---------------------------------------------------------------------------------------------------------------------
+bool EventManager::VUpdate(unsigned long maxMillis)
+{
+	unsigned long currMs = SDL_GetTicks();
+	unsigned long maxMs = ((maxMillis == IEventManager::kINFINITE) ? (IEventManager::kINFINITE) : (currMs + maxMillis));
+
+	// This section added to handle events from other threads.  Check out Chapter 20.
+	// IEventDataPtr pRealtimeEvent;
+	// while (m_realtimeEventQueue.try_pop(pRealtimeEvent))
+	// {
+	// 	VQueueEvent(pRealtimeEvent);
+
+	// 	currMs = SDL_GetTicks();
+	// 	if (maxMillis != IEventManager::kInfinite)
+	// 	{
+	// 		if (currMs >= maxMs)
+	// 		{
+	// 			GCC_ERROR("A realtime process is spamming the event manager");
+	// 		}
+	// 	}
+	// }
+
+	// swap active queues and clear the new queue after the swap
+	int queueToProcess = m_activeQueue;
+	m_activeQueue = (m_activeQueue + 1) % EVENTMANAGER_NUM_QUEUES;
+	m_queues[m_activeQueue].clear();
+
+	GCC_LOG("EventLoop", "Processing Event Queue " + ToStr(queueToProcess) + "; " + ToStr((unsigned long)m_queues[queueToProcess].size()) + " events to process");
+
+	// process the queue
+	while (!m_queues[queueToProcess].empty())
+	{
+		// pop the front of the queue
+		IEventDataPtr pEvent = m_queues[queueToProcess].front();
+		m_queues[queueToProcess].pop_front();
+		GCC_LOG("EventLoop", "\t\tProcessing Event " + std::string(pEvent->GetName()));
+
+		const EventType& eventType = pEvent->VGetEventType();
+
+		// find all the delegate functions registered for this event
+		auto findIt = m_eventListeners.find(eventType);
+		if (findIt != m_eventListeners.end())
+		{
+			const EventListenerList& eventListeners = findIt->second;
+            GCC_LOG("EventLoop", "\t\tFound " + ToStr((unsigned long)eventListeners.size()) + " delegates");
+
+            // call each listener
+			for (auto it = eventListeners.begin(); it != eventListeners.end(); ++it)
+			{
+                EventListenerDelegate listener = (*it);
+                GCC_LOG("EventLoop", "\t\tSending event " + std::string(pEvent->GetName()) + " to delegate");
+				listener(pEvent);
+			}
+		}
+
+		// check to see if time ran out
+		currMs = SDL_GetTicks();
+		if (maxMillis != IEventManager::kINFINITE && currMs >= maxMs)
+		{
+			GCC_LOG("EventLoop", "Aborting event processing; time ran out");
+			break;
+		}
+	}
+
+	// If we couldn't process all of the events, push the remaining events to the new active queue.
+	// Note: To preserve sequencing, go back-to-front inserting them at the head of the active queue
+	bool queueFlushed = (m_queues[queueToProcess].empty());
+	if (!queueFlushed)
+	{
+		while (!m_queues[queueToProcess].empty())
+		{
+			IEventDataPtr pEvent = m_queues[queueToProcess].back();
+			m_queues[queueToProcess].pop_back();
+			m_queues[m_activeQueue].push_front(pEvent);
+		}
+	}
+
+	return queueFlushed;
+}

+ 65 - 0
Source/GCC4/EventManager/EventManagerImpl.h

@@ -0,0 +1,65 @@
+#pragma once
+//========================================================================
+// EventMangerImpl.cpp : implementation side of the event system
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "EventManager.h"
+
+const unsigned int EVENTMANAGER_NUM_QUEUES = 2;
+
+class EventManager : public IEventManager
+{
+	typedef std::list<EventListenerDelegate> EventListenerList;
+	typedef std::map<EventType, EventListenerList> EventListenerMap;
+	typedef std::list<IEventDataPtr> EventQueue;
+	
+	EventListenerMap m_eventListeners;
+	EventQueue m_queues[EVENTMANAGER_NUM_QUEUES];
+	int m_activeQueue;  // index of actively processing queue; events enque to the opposing queue
+	
+public:
+	explicit EventManager(const char* pName, bool setAsGlobal);
+	virtual ~EventManager(void);
+
+    virtual bool VAddListener(const EventListenerDelegate& eventDelegate, const EventType& type);
+    virtual bool VRemoveListener(const EventListenerDelegate& eventDelegate, const EventType& type);
+
+    virtual bool VTriggerEvent(const IEventDataPtr& pEvent) const;
+    virtual bool VQueueEvent(const IEventDataPtr& pEvent);
+
+    virtual bool VUpdate(unsigned long maxMillis = kINFINITE);
+};

+ 63 - 0
Source/GCC4/EventManager/Events.cpp

@@ -0,0 +1,63 @@
+//========================================================================
+// Events.cpp : defines common game events
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/6
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+
+#include "Events.h"
+// #include "../Physics/PhysicsEventListener.h"
+#include "../LUAScripting/ScriptEvent.h"
+
+// To define a new event - you need a 32-bit GUID. 
+// In Visual Studio, go to Tools->Create GUID and grab the first bit.
+
+const EventType EvtData_Environment_Loaded::sk_EventType(0xa3814acd);
+const EventType EvtData_Remote_Environment_Loaded::sk_EventType(0x8E2AD6E6);
+const EventType EvtData_New_Actor::sk_EventType(0xe86c7c31);
+// const EventType EvtData_Move_Actor::sk_EventType(0xeeaa0a40);
+const EventType EvtData_Destroy_Actor::sk_EventType(0x77dd2b3a);
+const EventType EvtData_New_Render_Component::sk_EventType(0xaf4aff75);
+const EventType EvtData_Modified_Render_Component::sk_EventType(0x80fe9766);
+const EventType EvtData_Request_Start_Game::sk_EventType(0x11f2b19d);
+// const EventType EvtData_Remote_Client::sk_EventType(0x301693d5);
+// const EventType EvtData_Network_Player_Actor_Assignment::sk_EventType(0xa7c92f11);
+const EventType EvtData_Update_Tick::sk_EventType(0xf0f5d183);
+// const EventType EvtData_Decompress_Request::sk_EventType(0xc128a129);
+// const EventType EvtData_Decompression_Progress::sk_EventType(0x68de1f28);
+const EventType EvtData_Request_New_Actor::sk_EventType(0x40378c64);
+// const EventType EvtData_Request_Destroy_Actor::sk_EventType(0xf5395770);
+const EventType EvtData_PlaySound::sk_EventType(0x3d8118ee);

+ 507 - 0
Source/GCC4/EventManager/Events.h

@@ -0,0 +1,507 @@
+#pragma once
+//========================================================================
+// Events.h : defines common game events
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+
+#include "EventManager.h"
+#include "../GameCode4/GameCode.h"
+#include "../LUAScripting/ScriptEvent.h"
+#include "../Graphics3D/Scene.h"
+
+//---------------------------------------------------------------------------------------------------------------------
+// EvtData_New_Actor - This event is sent out when an actor is *actually* created.
+//---------------------------------------------------------------------------------------------------------------------
+class EvtData_New_Actor : public BaseEventData
+{
+	ActorId m_actorId;
+	GameViewId m_viewId;
+
+public:
+	static const EventType sk_EventType;
+
+	EvtData_New_Actor(void)
+	{
+		m_actorId = INVALID_ACTOR_ID;
+		m_viewId = gc_InvalidGameViewId;
+	}
+
+	explicit EvtData_New_Actor(ActorId actorId, GameViewId viewId = gc_InvalidGameViewId)
+		: m_actorId(actorId),
+		  m_viewId(viewId)
+	{
+	}
+
+	virtual void VDeserialize(std::istrstream& in)
+	{
+		in >> m_actorId;
+		in >> m_viewId;
+	}
+
+	virtual const EventType& VGetEventType(void) const
+	{
+		return sk_EventType;
+	}
+
+	virtual IEventDataPtr VCopy(void) const
+	{
+		return IEventDataPtr(GCC_NEW EvtData_New_Actor(m_actorId, m_viewId));
+	}
+
+	virtual void VSerialize(std::ostream& out) const
+	{
+		out << m_actorId << " ";
+		out << m_viewId << " ";
+	}
+	
+
+	virtual const char* GetName(void) const
+	{
+		return "EvtData_New_Actor";
+	}
+
+	const ActorId GetActorId(void) const
+	{
+		return m_actorId;
+	}
+
+	GameViewId GetViewId(void) const
+	{
+		return m_viewId;
+	}
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// EvtData_Destroy_Actor - sent when actors are destroyed	
+//---------------------------------------------------------------------------------------------------------------------
+class EvtData_Destroy_Actor : public BaseEventData
+{
+	ActorId m_id;
+
+public:
+	static const EventType sk_EventType;
+
+	explicit EvtData_Destroy_Actor(ActorId id = INVALID_ACTOR_ID)
+		: m_id(id)
+	{
+		//
+	}
+
+	virtual const EventType& VGetEventType(void) const
+	{
+		return sk_EventType;
+	}
+
+	virtual IEventDataPtr VCopy(void) const
+	{
+		return IEventDataPtr(GCC_NEW EvtData_Destroy_Actor(m_id));
+	}
+
+	virtual void VSerialize(std::ostrstream &out) const
+	{
+		out << m_id;
+	}
+
+	virtual void VDeserialize(std::istrstream& in)
+	{
+		in >> m_id;
+	}
+
+	virtual const char* GetName(void) const
+	{
+		return "EvtData_Destroy_Actor";
+	}
+
+	ActorId GetId(void) const { return m_id; }
+};
+
+//---------------------------------------------------------------------------------------------------------------------
+// EvtData_New_Render_Component - This event is sent out when an actor is *actually* created.
+//---------------------------------------------------------------------------------------------------------------------
+class EvtData_New_Render_Component : public BaseEventData
+{
+	ActorId m_actorId;
+	std::shared_ptr<SceneNode> m_pSceneNode;
+
+public:
+	static const EventType sk_EventType;
+
+	EvtData_New_Render_Component(void) 
+	{
+		m_actorId = INVALID_ACTOR_ID;
+	}
+
+	explicit EvtData_New_Render_Component(ActorId actorId, std::shared_ptr<SceneNode> pSceneNode) 
+		: m_actorId(actorId),
+		  m_pSceneNode(pSceneNode)
+	{
+	}
+
+	virtual void VSerialize(std::ostrstream& out) const
+	{
+		GCC_ERROR(GetName() + std::string(" should not be serialzied!"));
+	}
+
+	virtual void VDeserialize(std::istrstream& in)
+	{
+		GCC_ERROR(GetName() + std::string(" should not be serialzied!"));
+	}
+
+	virtual const EventType& VGetEventType(void) const
+	{
+		return sk_EventType;
+	}
+
+	virtual IEventDataPtr VCopy(void) const
+	{
+		return IEventDataPtr(GCC_NEW EvtData_New_Render_Component(m_actorId, m_pSceneNode));
+	}
+
+	virtual const char* GetName(void) const
+	{
+		return "EvtData_New_Render_Component";
+	}
+
+	const ActorId GetActorId(void) const
+	{
+		return m_actorId;
+	}
+
+	std::shared_ptr<SceneNode> GetSceneNode(void) const
+	{
+		return m_pSceneNode;
+	}
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// EvtData_Modified_Render_Component - This event is sent out when a render component is changed
+//   NOTE: This class is not described in the book!
+//---------------------------------------------------------------------------------------------------------------------
+class EvtData_Modified_Render_Component : public BaseEventData
+{
+	ActorId m_id;
+
+public:
+	static const EventType sk_EventType;
+
+	virtual const EventType& VGetEventType(void) const
+	{
+		return sk_EventType;
+	}
+
+	EvtData_Modified_Render_Component(void)
+	{
+		m_id = INVALID_ACTOR_ID;
+	}
+
+	EvtData_Modified_Render_Component(ActorId id)
+		: m_id(id)
+	{
+	}
+
+	virtual void VSerialize(std::ostrstream &out) const
+	{
+		out << m_id;
+	}
+
+	virtual void VDeserialize(std::istrstream& in)
+	{
+		in >> m_id;
+	}
+
+	virtual IEventDataPtr VCopy() const
+	{
+		return IEventDataPtr(GCC_NEW EvtData_Modified_Render_Component(m_id));
+	}
+
+	virtual const char* GetName(void) const
+	{
+		return "EvtData_Modified_Render_Component";
+	}
+
+	ActorId GetActorId(void) const
+	{
+		return m_id;
+	}
+};
+//---------------------------------------------------------------------------------------------------------------------
+// EvtData_Environment_Loaded - this event is sent when a new game is started
+//---------------------------------------------------------------------------------------------------------------------
+class EvtData_Environment_Loaded : public BaseEventData
+{
+public:
+	static const EventType sk_EventType;
+
+    EvtData_Environment_Loaded(void) { }
+	virtual const EventType& VGetEventType(void) const	{ return sk_EventType; }
+	virtual IEventDataPtr VCopy(void) const
+		{ return IEventDataPtr( GCC_NEW EvtData_Environment_Loaded( ) ); }
+    virtual const char* GetName(void) const  { return "EvtData_Environment_Loaded";  }
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// EvtData_Environment_Loaded - this event is sent when a client has loaded its environment
+//   This is special because we only want this event to go from client to server, and stop there. The
+//   EvtData_Environment_Loaded is received by server and proxy logics alike. Thy to do this with just the above 
+//   event and you'll get into an endless loop of the EvtData_Environment_Loaded event making infinite round trips
+//   from client to server.
+//
+// FUTURE_WORK: It would be an interesting idea to add a "Private" type of event that is addressed only to a specific 
+//              listener. Of course, that might be a really dumb idea too - someone will have to try it!
+//---------------------------------------------------------------------------------------------------------------------
+class EvtData_Remote_Environment_Loaded : public BaseEventData
+{
+public:
+	static const EventType sk_EventType;
+
+    EvtData_Remote_Environment_Loaded(void) { }
+	virtual const EventType& VGetEventType(void) const	{ return sk_EventType; }
+	virtual IEventDataPtr VCopy(void) const
+		{ return IEventDataPtr( GCC_NEW EvtData_Remote_Environment_Loaded( ) ); }
+    virtual const char* GetName(void) const  { return "EvtData_Remote_Environment_Loaded";  }
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// EvtData_Request_Start_Game - this is sent by the authoritative game logic to all views so they will load a game level.
+//---------------------------------------------------------------------------------------------------------------------
+class EvtData_Request_Start_Game : public BaseEventData
+{
+public:
+	static const EventType sk_EventType;
+
+	EvtData_Request_Start_Game(void) { }
+
+	virtual const EventType& VGetEventType(void) const
+	{
+		return sk_EventType;
+	}
+
+	virtual IEventDataPtr VCopy() const
+	{
+		return IEventDataPtr( GCC_NEW EvtData_Request_Start_Game( ) );
+	}
+
+	virtual const char* GetName(void) const
+	{
+		return "EvtData_Request_Start_Game";
+	}
+};
+
+
+//---------------------------------------------------------------------------------------------------------------------
+// EvtData_Update_Tick - sent by the game logic each game tick
+//---------------------------------------------------------------------------------------------------------------------
+class EvtData_Update_Tick : public BaseEventData
+{
+	int m_DeltaMilliseconds;
+
+public:
+	static const EventType sk_EventType;
+
+	explicit EvtData_Update_Tick( const int deltaMilliseconds )
+		: m_DeltaMilliseconds( deltaMilliseconds )
+	{
+	}
+
+	virtual const EventType& VGetEventType( void ) const
+	{
+		return sk_EventType;
+	}
+
+	virtual IEventDataPtr VCopy() const
+	{
+		return IEventDataPtr (GCC_NEW EvtData_Update_Tick ( m_DeltaMilliseconds ) );
+	}
+
+	virtual void Serialize( std::ostrstream & out )
+	{
+		GCC_ERROR("You should not be serializing update ticks!");
+	}
+
+	virtual const char* GetName(void) const
+	{
+		return "EvtData_Update_Tick";
+	}
+};
+
+//---------------------------------------------------------------------------------------------------------------------
+// class EvtData_Request_New_Actor				
+// This event is sent by a server asking Client proxy logics to create new actors from their local resources.
+// It can be sent from script or via code.
+// This event is also sent from the server game logic to client logics AFTER it has created a new actor. The logics will allow follow suit to stay in sync.
+//---------------------------------------------------------------------------------------------------------------------
+class EvtData_Request_New_Actor : public BaseEventData
+{
+	std::string m_actorResource;
+	bool m_hasInitialTransform;
+	glm::mat4 m_initialTransform;
+	ActorId m_serverActorId;
+	GameViewId m_viewId;
+
+public:
+	static const EventType sk_EventType;
+
+	EvtData_Request_New_Actor()
+	{
+		m_actorResource = "";
+		m_hasInitialTransform = false;
+		m_initialTransform = glm::mat4(1.0f);
+		m_serverActorId = -1;
+		m_viewId = gc_InvalidGameViewId;
+	}
+
+	explicit EvtData_Request_New_Actor(const std::string &actorResource, std::optional<const glm::mat4> initialTransform=std::nullopt, const ActorId serverActorId = INVALID_ACTOR_ID, const GameViewId viewId = gc_InvalidGameViewId)
+	{
+		m_actorResource = actorResource;
+		if (initialTransform)
+		{
+			m_hasInitialTransform = true;
+			m_initialTransform = *initialTransform;
+		}
+		else
+			m_hasInitialTransform = false;
+
+		m_serverActorId = serverActorId;
+		m_viewId = viewId;
+	}
+
+	virtual const EventType& VGetEventType(void) const
+	{
+		return sk_EventType;
+	}
+
+	virtual void VDeserialize(std::istrstream & in)
+	{
+		in >> m_actorResource;
+		in >> m_hasInitialTransform;
+		if (m_hasInitialTransform)
+		{
+			for (int i=0; i<4; i++)
+			{
+				for (int j=0; j<4; ++j)
+				{
+					in >> m_initialTransform[i][j];
+				}
+			}
+		}
+		in >> m_serverActorId;
+		in >> m_viewId;
+	}
+
+	virtual IEventDataPtr VCopy() const
+	{
+		return IEventDataPtr (GCC_NEW EvtData_Request_New_Actor(m_actorResource, (m_hasInitialTransform) ? std::optional(m_initialTransform) : std::nullopt, m_serverActorId, m_viewId));
+	}
+
+	virtual void VSerialize( std::ostrstream & out ) const
+	{
+		out << m_actorResource << " ";
+		out << m_hasInitialTransform << " ";
+		if (m_hasInitialTransform)
+		{
+			for (int i=0; i<4; ++i)
+			{
+				for (int j=0; j<4; ++j)
+				{
+					out << m_initialTransform[i][j];
+				}
+			}
+		}
+	}
+
+	virtual const char* GetName(void) const { return "EvtData_Request_New_Actor"; }
+
+	const std::string &GetActorResource(void) const { return m_actorResource; }
+	const glm::mat4 *GetInitialTransform(void) const { return (m_hasInitialTransform) ? &m_initialTransform : NULL; }
+	const ActorId GetServerActorId(void) const { return m_serverActorId; }
+	GameViewId GetViewId(void) const { return m_viewId; }
+};
+
+//---------------------------------------------------------------------------------------------------------------------
+// EvtData_PlaySound - sent by any system wishing for a HumanView to play a sound
+//---------------------------------------------------------------------------------------------------------------------
+class EvtData_PlaySound : public ScriptEvent
+{
+    std::string m_soundResource;
+
+public:
+    static const EventType sk_EventType;
+
+    EvtData_PlaySound(void) { }
+    EvtData_PlaySound(const std::string& soundResource)
+        : m_soundResource(soundResource)
+    {
+    }
+
+    virtual const EventType& VGetEventType(void) const
+    {
+        return sk_EventType;
+    }
+
+    virtual IEventDataPtr VCopy() const
+    {
+        return IEventDataPtr(GCC_NEW EvtData_PlaySound(m_soundResource));
+    }
+
+    virtual void VSerialize(std::ostrstream& out) const
+    {
+        out << m_soundResource;
+    }
+
+    virtual void VDeserialize(std::istrstream& in)
+    {
+        in >> m_soundResource;
+    }
+
+    const std::string& GetResource(void) const
+    {
+        return m_soundResource;
+    }
+
+    virtual const char* GetName(void) const
+    {
+        return "EvtData_PlaySound";
+    }
+
+    virtual bool VBuildEventFromScript(void);
+
+    EXPORT_FOR_SCRIPT_EVENT(EvtData_PlaySound);
+};

+ 449 - 0
Source/GCC4/GameCode4/BaseGameLogic.cpp

@@ -0,0 +1,449 @@
+//========================================================================
+// BaseGameLogic.cpp : defines game logic class
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+
+#include "../EventManager/Events.h"				// only for EvtData_Game_State
+#include "../ResourceCache/XmlResource.h"
+#include "../UserInterface/HumanView.h"  // [rez] not ideal, but the loading sequence needs to know if this is a human view
+
+#include "BaseGameLogic.h"
+
+//========================================================================
+//
+// LevelManager implementation
+//
+//========================================================================
+
+bool LevelManager::Initialize(std::vector<std::string> &levels)
+{
+	std::vector<std::string>::iterator i = levels.begin();
+	while (i != levels.end())
+	{
+		m_Levels.push_back(*i);
+		++i;
+	}
+	return true;
+}
+
+
+
+
+//========================================================================
+//
+// BaseGameLogic implementation
+//
+//========================================================================
+
+BaseGameLogic::BaseGameLogic()
+{
+	m_Lifetime              = 0;
+	m_State                 = BGS_Initializing;
+	m_bProxy                = false;
+	m_ExpectedPlayers       = 0;
+	m_ExpectedRemotePlayers = 0;
+	m_ExpectedAI            = 0;
+	m_HumanPlayersAttached  = 0;
+	m_AIPlayersAttached     = 0;
+	m_HumanGamesLoaded      = 0;
+
+	m_pLevelManager = GCC_NEW LevelManager;
+	// GCC_ASSERT(m_pProcessManager && m_pLevelManager);
+
+	// TODO(munnellg) - book passes levels directly, but my compiler doesn't like that. Find out why
+	std::vector<std::string> levels = g_pApp->m_ResCache->Match("world/*.xml");
+	m_pLevelManager->Initialize(levels);
+}
+
+BaseGameLogic::~BaseGameLogic()
+{
+	// MrMike: 12-Apr-2009 
+	//   Added this to explicitly remove views from the game logic list.
+	while (!m_gameViews.empty())
+		m_gameViews.pop_front();
+
+	SAFE_DELETE(m_pLevelManager);
+	// SAFE_DELETE(m_pProcessManager);
+	SAFE_DELETE(m_pActorFactory);
+
+	// destroy all actors
+	for (auto it = m_actors.begin(); it != m_actors.end(); ++it)
+		it->second->Destroy();
+	m_actors.clear();
+
+	// IEventManager::Get()->VRemoveListener(MakeDelegate(this, &BaseGameLogic::RequestDestroyActorDelegate), EvtData_Request_Destroy_Actor::sk_EventType);
+}
+
+bool BaseGameLogic::Init(void)
+{
+    m_pActorFactory = VCreateActorFactory();
+    // m_pPathingGraph.reset(CreatePathingGraph());
+
+    // IEventManager::Get()->VAddListener(MakeDelegate(this, &BaseGameLogic::RequestDestroyActorDelegate), EvtData_Request_Destroy_Actor::sk_EventType);
+
+    return true;
+}
+
+bool BaseGameLogic::VLoadGame(const char* levelResource)
+{
+	// Grab the root XML node
+	TiXmlElement* pRoot = XmlResourceLoader::LoadAndReturnRootXmlElement(levelResource);
+	if (!pRoot)
+	{
+		GCC_ERROR("Failed to find level resource file: " + std::string(levelResource));
+		return false;
+	}
+
+	// pre and post load scripts
+	const char* preLoadScript = NULL;
+	const char* postLoadScript = NULL;
+
+	// parse the pre & post script attributes
+	TiXmlElement* pScriptElement = pRoot->FirstChildElement("Script");
+	if (pScriptElement)
+	{
+		preLoadScript = pScriptElement->Attribute("preLoad");
+		postLoadScript = pScriptElement->Attribute("postLoad");
+	}
+
+	// load the pre-load script if there is one
+	if (preLoadScript)
+	{
+		Resource resource(preLoadScript);
+		std::shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);
+	}
+
+	// load all initial actors
+	TiXmlElement* pActorsNode = pRoot->FirstChildElement("StaticActors");
+	if (pActorsNode)
+	{
+		for (TiXmlElement* pNode = pActorsNode->FirstChildElement(); pNode; pNode = pNode->NextSiblingElement())
+		{
+			const char* actorResource = pNode->Attribute("resource");
+
+			StrongActorPtr pActor = VCreateActor(actorResource, pNode);
+			if (pActor)
+			{
+				// fire an event letting everyone else know that we created a new actor
+				std::shared_ptr<EvtData_New_Actor> pNewActorEvent(GCC_NEW EvtData_New_Actor(pActor->GetId()));
+				IEventManager::Get()->VQueueEvent(pNewActorEvent);
+			}
+		}
+	}
+
+	// initialize all human views
+	for (auto it = m_gameViews.begin(); it != m_gameViews.end(); ++it)
+	{
+		std::shared_ptr<IGameView> pView = *it;
+		if (pView->VGetType() == GameView_Human)
+		{
+			std::shared_ptr<HumanView> pHumanView = static_pointer_cast<HumanView, IGameView>(pView);
+			pHumanView->LoadGame(pRoot);
+		}
+	}
+
+    // register script events from the engine
+	//   [mrmike] this was moved to the constructor post-press, since this function can be called when new levels are loaded by the game or editor
+    // RegisterEngineScriptEvents();
+
+    // call the delegate load function
+    if (!VLoadGameDelegate(pRoot))
+        return false;  // no error message here because it's assumed VLoadGameDelegate() kicked out the error
+
+    // load the post-load script if there is one
+    if (postLoadScript)
+    {
+        Resource resource(postLoadScript);
+        std::shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);  // this actually loads the XML file from the zip file
+    }
+
+	// trigger the Environment Loaded Game event - only then can player actors and AI be spawned!
+	if (m_bProxy)
+	{
+		std::shared_ptr<EvtData_Remote_Environment_Loaded> pNewGameEvent(GCC_NEW EvtData_Remote_Environment_Loaded);
+		IEventManager::Get()->VTriggerEvent(pNewGameEvent);
+	}
+	else
+	{
+		std::shared_ptr<EvtData_Environment_Loaded> pNewGameEvent(GCC_NEW EvtData_Environment_Loaded);
+		IEventManager::Get()->VTriggerEvent(pNewGameEvent);
+	}
+	return true;
+}
+
+void BaseGameLogic::VSetProxy() 
+{
+	m_bProxy = true; 
+
+	// IEventManager::Get()->VAddListener(MakeDelegate(this, &BaseGameLogic::RequestNewActorDelegate), EvtData_Request_New_Actor::sk_EventType);
+
+	// m_pPhysics.reset(CreateNullPhysics());
+}
+
+StrongActorPtr BaseGameLogic::VCreateActor(
+		const std::string &actorResource,
+		TiXmlElement* overrides,
+		std::optional<const glm::mat4> initialTransform,
+		const ActorId serversActorId
+) {
+	
+	GCC_ASSERT(m_pActorFactory);
+	if (!m_bProxy && serversActorId != INVALID_ACTOR_ID)
+		return StrongActorPtr();
+
+	if (m_bProxy && serversActorId == INVALID_ACTOR_ID)
+		return StrongActorPtr();
+
+	StrongActorPtr pActor = m_pActorFactory->CreateActor(actorResource.c_str(), overrides, initialTransform, serversActorId);
+	if (pActor)
+	{
+		m_actors.insert(std::make_pair(pActor->GetId(), pActor));
+		if (!m_bProxy && (m_State==BGS_SpawningPlayersActors || m_State==BGS_Running))
+		{
+			std::shared_ptr<EvtData_Request_New_Actor> pNewActor(GCC_NEW EvtData_Request_New_Actor(actorResource, initialTransform, pActor->GetId()));
+			IEventManager::Get()->VTriggerEvent(pNewActor);
+		}
+		return pActor;
+	}
+	else
+	{
+		return StrongActorPtr();
+	}
+}
+
+void BaseGameLogic::VDestroyActor(const ActorId actorId)
+{
+	std::shared_ptr<EvtData_Destroy_Actor> pEvent(GCC_NEW EvtData_Destroy_Actor(actorId));
+	IEventManager::Get()->VTriggerEvent(pEvent);
+
+	auto findIt = m_actors.find(actorId);
+	if (findIt != m_actors.end())
+	{
+		findIt->second->Destroy();
+		m_actors.erase(findIt);
+	}
+}
+
+WeakActorPtr BaseGameLogic::VGetActor(const ActorId actorId)
+{
+	ActorMap::iterator findIt = m_actors.find(actorId);
+	if (findIt != m_actors.end())
+		return findIt->second;
+	return WeakActorPtr();
+}
+
+void BaseGameLogic::VModifyActor(const ActorId actorId, TiXmlElement *override)
+{
+	GCC_ASSERT(m_pActorFactory);
+	if (!m_pActorFactory)
+		return;
+
+	auto findIt = m_actors.find(actorId);
+	if (findIt != m_actors.end())
+	{
+		m_pActorFactory->ModifyActor(findIt->second, override);
+	}
+}
+
+void BaseGameLogic::VOnUpdate(float time, float elapsedTime)
+{
+	int deltaMilliseconds = int(elapsedTime * 1000.0f);
+	m_Lifetime += elapsedTime;
+
+	switch(m_State)
+	{
+		case BGS_Initializing:
+		{
+			// If we get to here we're ready to attach players
+			VChangeState(BGS_MainMenu);
+			break;
+		}
+		case BGS_MainMenu:
+		{
+			break;
+		}
+		case BGS_LoadingGameEnvironment:
+		{
+/***
+			// [mrmike] This was modified a little from what you see in the book - VLoadGame() is now called from 
+			//          BaseGameLogic::VChangeState()
+			//
+			if (!g_pApp->VLoadGame())
+			{
+				GCC_ERROR("The game failed to load.");
+				g_pApp->AbortGame();
+			}
+***/
+			break;
+		}
+		case BGS_WaitingForPlayersToLoadEnvironment:
+		{
+			if (m_ExpectedPlayers + m_ExpectedRemotePlayers <= m_HumanGamesLoaded)
+			{
+				VChangeState(BGS_SpawningPlayersActors);
+			}
+			break;
+		}
+		case BGS_SpawningPlayersActors:
+		{
+			VChangeState(BGS_Running);
+			break;
+		}
+		case BGS_WaitingForPlayers:
+		{
+			if (m_ExpectedPlayers + m_ExpectedRemotePlayers == m_HumanPlayersAttached)
+			{
+				// The server sends us the level name as a part of the login message. 
+				// We have to wait until it arrives before loading the level
+				if (!g_pApp->m_Options.m_Level.empty())
+				{
+					VChangeState(BGS_LoadingGameEnvironment);
+				}
+			}
+			break;
+		}
+		case BGS_Running:
+		{
+			// m_pProcessManager->UpdateProcesses(deltaMilliseconds);
+
+			// if (m_pPhysics && !m_bProxy)
+			// {
+			// 	m_pPhysics->VOnUpdate(elapsedTime);
+			// 	m_pPhysics->VSyncVisibleScene();
+			// }
+			break;
+		}
+		default:
+			GCC_ERROR("Unrecognized state.");
+	}
+
+	// update all game views
+	for (GameViewList::iterator it = m_gameViews.begin(); it != m_gameViews.end(); ++it)
+	{
+		(*it)->VOnUpdate(deltaMilliseconds);
+	}
+
+	// update game actors
+	// for (ActorMap::const_iterator it = m_actors.begin(); it != m_actors.end(); ++it)
+	// {
+	// 	it->second->Update(deltaMilliseconds);
+	// }
+}
+
+//
+// BaseGameLogic::VChangeState				- Chapter 19, page 710
+//
+void BaseGameLogic::VChangeState(BaseGameState newState)
+{
+	// TODO(munnellg) - implement
+	if (newState==BGS_WaitingForPlayers)
+	{
+		// Get rid of the Main Menu
+		m_gameViews.pop_front();
+		// Note: Split screen support would require this to change!
+		m_ExpectedPlayers = 1;
+		m_ExpectedRemotePlayers = g_pApp->m_Options.m_expectedPlayers - 1;
+		m_ExpectedAI = g_pApp->m_Options.m_numAIs;
+
+		if (!g_pApp->m_Options.m_gameHost.empty())
+		{
+			VSetProxy();
+			m_ExpectedAI = 0;				// the server will create these
+			m_ExpectedRemotePlayers = 0;	// the server will create these
+
+			// TODO(munnellg) - implement
+			// if (!g_pApp->AttachAsClient())
+			// {
+			// 	// Throw up a main menu
+			// 	VChangeState(BGS_MainMenu);
+			// 	return
+			// }
+		}
+		// else if (m_ExpectedRemotePlayers > 0)
+		// {
+			// TODO(munnellg) - implement for network games		
+		// }
+	}
+	else if (newState == BGS_LoadingGameEnvironment)
+	{
+		m_State = newState;
+		if (!g_pApp->VLoadGame())
+		{
+			GCC_ERROR("The game failed to load.");
+			g_pApp->AbortGame();
+		}
+		else
+		{
+			VChangeState(BGS_WaitingForPlayersToLoadEnvironment);			// we must wait for all human player to report their environments are loaded.
+			return;
+		}
+	}
+	m_State = newState;
+}
+
+// Chapter 19/20 refactor work
+//   - move physics pointer into BaseGameLogic
+//   - but make the inherited logic choose the implementation
+void BaseGameLogic::VRenderDiagnostics() 
+{
+	if (m_RenderDiagnostics)
+	{
+		// TODO(munnellg) - uncomment this when we have physics
+		// m_pPhysics->VRenderDiagnostics();
+	}
+}
+
+void BaseGameLogic::VAddView(std::shared_ptr<IGameView> pView, ActorId actorId)
+{
+	// This makes sure that all views have a non-zero view id.
+	int viewId = static_cast<int>(m_gameViews.size());
+	m_gameViews.push_back(pView);
+	pView->VOnAttach(viewId, actorId);
+	pView->VOnRestore();
+}
+
+void BaseGameLogic::VRemoveView(std::shared_ptr<IGameView> pView)
+{
+	m_gameViews.remove(pView);
+}
+
+
+ActorFactory* BaseGameLogic::VCreateActorFactory(void)
+{
+    return GCC_NEW ActorFactory;
+}

+ 152 - 0
Source/GCC4/GameCode4/BaseGameLogic.h

@@ -0,0 +1,152 @@
+#pragma once
+//========================================================================
+// BaseGameLogic.h : Defines the Base Game Logic class 
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "interfaces.h"
+
+#include "../Utilities/Math.h"
+#include "../Actors/Actor.h"
+#include "../Actors/ActorFactory.h"
+
+#include <vector>
+
+class LevelManager;
+
+enum BaseGameState
+{
+	BGS_Invalid,
+	BGS_Initializing,
+	BGS_MainMenu,
+	BGS_WaitingForPlayers,
+	BGS_LoadingGameEnvironment,
+	BGS_WaitingForPlayersToLoadEnvironment,
+	BGS_SpawningPlayersActors,
+	BGS_Running
+};
+
+typedef std::map<ActorId, StrongActorPtr> ActorMap;
+typedef std::string Level;
+
+class LevelManager
+{
+public:
+	const std::vector<Level> &GetLevels() const { return m_Levels; }
+	const int GetCurrentLevel() const { return m_CurrentLevel; }
+	bool Initialize(std::vector<std::string> &levels);
+
+protected:
+	std::vector<Level> m_Levels;
+	int m_CurrentLevel;
+};
+
+
+
+class BaseGameLogic : public IGameLogic
+{
+	friend class GameCodeApp;						// This is only to gain access to the view list
+
+protected:
+	float m_Lifetime;								//indicates how long this game has been in session
+	BaseGameState m_State;							// game state: loading, running, etc.
+	ActorMap m_actors;
+	int m_ExpectedPlayers;							// how many local human players
+	int m_ExpectedRemotePlayers;					// expected remote human players
+	int m_ExpectedAI;								// how many AI players
+	int m_HumanPlayersAttached;
+	int m_AIPlayersAttached;
+	int m_HumanGamesLoaded;
+	GameViewList m_gameViews;						// views that are attached to our game
+	ActorFactory* m_pActorFactory;
+	
+	bool m_bProxy;									// set if this is a proxy game logic, not a real one
+
+	bool m_RenderDiagnostics;						// Are we rendering diagnostics?
+
+	LevelManager* m_pLevelManager;					// Manages loading and chaining levels
+
+public:
+
+	BaseGameLogic();
+	virtual ~BaseGameLogic();
+	bool Init(void);
+
+	void SetProxy(bool isProxy) 
+	{ 
+		m_bProxy = isProxy; 
+	}
+	const bool IsProxy() const { return m_bProxy; }
+
+	// [mrmike] CanRunLua() is a bit of a hack - but I can't have Lua scripts running on the clients. They should belong to the logic.
+	// FUTURE WORK - Perhaps the scripts can have a marker or even a special place in the resource file for any scripts that can run on remote clients
+	const bool CanRunLua() const { return !IsProxy() || GetState()!=BGS_Running; }
+
+	virtual void VAddView(std::shared_ptr<IGameView> pView, ActorId actorId=INVALID_ACTOR_ID);
+	virtual void VRemoveView(std::shared_ptr<IGameView> pView);
+
+	virtual StrongActorPtr VCreateActor(
+		const std::string &actorResource,
+		TiXmlElement *overrides,
+		std::optional<const glm::mat4> initialTransform=std::nullopt,
+		const ActorId serversActorId=INVALID_ACTOR_ID					// [rez] note: don't store this strong pointer outside of this class
+	);
+	virtual void VDestroyActor(const ActorId actorId);
+	virtual WeakActorPtr VGetActor(const ActorId actorId);
+	virtual void VModifyActor(const ActorId actorId, TiXmlElement *override);
+
+	// Level management
+	const LevelManager* GetLevelManager() { return m_pLevelManager; }
+	virtual bool VLoadGame(const char* levelResource) override;  // [rez] Subclasses shouldn't override this function; use VLoadGameDelegate() instead
+	virtual void VSetProxy();
+
+	// Logic Update
+	virtual void VOnUpdate(float time, float elapsedTime);
+
+	// Changing Game Logic State
+	virtual void VChangeState(BaseGameState newState);
+	const BaseGameState GetState() const { return m_State; }
+
+	// Render Diagnostics
+	void ToggleRenderDiagnostics() { m_RenderDiagnostics = !m_RenderDiagnostics; }
+	virtual void VRenderDiagnostics();
+
+protected:
+	virtual ActorFactory* VCreateActorFactory(void);
+
+	// [rez] Override this function to do any game-specific loading.
+    virtual bool VLoadGameDelegate(TiXmlElement* pLevelData) { return true; }
+};

+ 588 - 0
Source/GCC4/GameCode4/GameCode.cpp

@@ -0,0 +1,588 @@
+//========================================================================
+// GameCode.cpp : Defines the Application layer for GameCode4
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+
+#include "../Mainloop/Initialization.h"
+#include "../Actors/BaseScriptComponent.h"
+#include "../ResourceCache/ResCache.h"
+#include "../Graphics3D/OpenGLRenderer.h"
+#include "../ResourceCache/XmlResource.h"
+#include "../LUAScripting/ScriptExports.h"
+#include "../LUAScripting/ScriptProcess.h"
+#include "../LUAScripting/LuaStateManager.h"
+#include "../EventManager/EventManagerImpl.h"
+#include "../Debugging/Logger.h"
+#include "../Utilities/Dialogs.h"
+
+#include <imgui.h>
+#include <imgui_impl_sdl3.h>
+#include <imgui_impl_opengl3.h>
+#include <GL/glew.h>
+
+GameCodeApp *g_pApp = NULL;
+
+const char* SCRIPT_PREINIT_FILE = "Scripts/PreInit.lua";
+const unsigned int SCREEN_REFRESH_RATE(1000/60);
+
+//========================================================================
+//
+// GameCodeApp implementation
+//
+//========================================================================
+
+GameCodeApp::GameCodeApp()
+{
+	g_pApp = this;
+	m_pGame = NULL;
+
+	m_bIsRunning = false;
+
+	m_bQuitRequested = false;
+	m_bQuitting = false;
+}
+
+//===================================================================
+// Win32 Specific Stuff
+//
+// InitInstance - this checks system resources, creates your window, and launches the game
+//
+// preprocessor macro setting in the C++ options of the project provides the base macro
+// C preprocessor string concatenation takes care of the rest.
+//
+// GameCodeApp::InitInstance - Chapter 5, page 136
+//
+//===================================================================
+
+bool GameCodeApp::InitInstance(int screenWidth, int screenHeight)
+{
+	// Check for adequate machine resources.
+	bool resourceCheck = false;
+	while (!resourceCheck)
+	{
+		const size_t physicalRAM = 512 * MEGABYTE;
+		const size_t virtualRAM = 1024 * MEGABYTE;
+		const size_t diskSpace = 10 * MEGABYTE;
+		if (!CheckStorage(diskSpace))
+			return false;
+
+		const unsigned int minCpuSpeed = 1300;			// 1.3Ghz
+		unsigned int thisCPU = ReadCPUSpeed();
+		if (thisCPU < minCpuSpeed)
+		{
+			GCC_ERROR("GetCPUSpeed reports CPU is too slow for this game.");
+			return false;
+		}
+
+		resourceCheck = true;
+	}
+
+	IResourceFile *zipFile = (m_bIsEditorRunning || m_Options.m_useDevelopmentDirectories) ?
+		GCC_NEW DevelopmentResourceZipFile(L"Assets.zip", DevelopmentResourceZipFile::Editor) :
+		GCC_NEW ResourceZipFile(L"Assets.zip");
+
+	m_ResCache = GCC_NEW ResCache(50, zipFile);
+
+	if (!m_ResCache->Init())
+	{
+		GCC_ERROR("Failed to initialize resource cache!  Are your paths set up correctly?");
+		return false;
+	}
+
+	// extern std::shared_ptr<IResourceLoader> CreateWAVResourceLoader();
+	// extern std::shared_ptr<IResourceLoader> CreateOGGResourceLoader();
+	extern std::shared_ptr<IResourceLoader> CreateDDSResourceLoader();
+	extern std::shared_ptr<IResourceLoader> CreateJPGResourceLoader();
+	extern std::shared_ptr<IResourceLoader> CreateXmlResourceLoader();
+	extern std::shared_ptr<IResourceLoader> CreateGlbMeshResourceLoader();
+	extern std::shared_ptr<IResourceLoader> CreateScriptResourceLoader();
+
+	// Note - register these in order from least specific to most specific! They get pushed onto a list.
+	// RegisterLoader is discussed in Chapter 5, page 142
+	// m_ResCache->RegisterLoader(CreateWAVResourceLoader());
+	// m_ResCache->RegisterLoader(CreateOGGResourceLoader());
+	// m_ResCache->RegisterLoader(CreateDDSResourceLoader());
+	m_ResCache->RegisterLoader(CreateJPGResourceLoader());
+	m_ResCache->RegisterLoader(CreateXmlResourceLoader());
+	m_ResCache->RegisterLoader(CreateGlbMeshResourceLoader());
+	m_ResCache->RegisterLoader(CreateScriptResourceLoader());
+	
+	if(!LoadStrings("English"))
+	{
+		GCC_ERROR("Failed to load strings");
+		return false;
+	}
+
+	// Rez up the Lua State manager now, and run the initial script - discussed in Chapter 5, page 144.
+	if (!LuaStateManager::Create())
+	{
+		GCC_ERROR("Failed to initialize Lua");
+		return false;
+	}
+
+	// Load the preinit file.  This is within braces to create a scope and destroy the resource once it's loaded.  We
+	// don't need to do anything with it, we just need to load it.
+	{
+		Resource resource(SCRIPT_PREINIT_FILE);
+		std::shared_ptr<ResHandle> pResourceHandle = m_ResCache->GetHandle(&resource);  // this actually loads the script from the zip file
+	}
+
+	// // Register function exported from C++
+	ScriptExports::Register();
+	ScriptProcess::RegisterScriptClass();
+	BaseScriptComponent::RegisterScriptFunctions();
+
+	// The event manager should be created next so that subsystems can hook in as desired.
+	// Discussed in Chapter 5, page 144
+	m_pEventManager = GCC_NEW EventManager("GameCodeApp Event Mgr", true);
+	if (!m_pEventManager)
+	{
+		GCC_ERROR("Failed to create EventManager.");
+		return false;
+	}
+
+	SDL_InitFlags initSystems = SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMEPAD | SDL_INIT_EVENTS;
+	if (!SDL_Init(initSystems)) {
+		GCC_ERROR(SDL_GetError());
+		return false;
+	}
+
+	static int const OPENGL_MAJOR_VERSION = 4;
+	static int const OPENGL_MINOR_VERSION = 6;
+	
+	if (!SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, OPENGL_MAJOR_VERSION)) {
+		GCC_ERROR(SDL_GetError());
+	}
+	
+	if (!SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, OPENGL_MINOR_VERSION)) {
+		GCC_ERROR(SDL_GetError());	
+	}
+	
+	if (!SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1)) {
+		GCC_ERROR(SDL_GetError());		
+	}
+	
+	if (!SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE)) {
+	    GCC_ERROR(SDL_GetError());
+	}
+
+	if (!SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG)) {
+		GCC_ERROR(SDL_GetError());	
+	}
+
+	m_Window = SDL_CreateWindow(
+		VGetGameTitle().c_str(), 
+		screenWidth, 
+		screenHeight, 
+		/*settings.window_flags |*/ SDL_WINDOW_OPENGL
+	);
+
+	if (!m_Window) {
+		GCC_ERROR(SDL_GetError());
+		return false;
+	}
+
+	// TODO(munnellg) - Set an icon
+	// SDL_SetWindowIcon(m_Window, VGetIcon());
+
+	m_GlContext = SDL_GL_CreateContext(m_Window);
+	if (!m_GlContext) {
+		GCC_ERROR(SDL_GetError());
+		return false;
+	}
+
+	GLuint err = glewInit();
+	if (err != GLEW_OK) {
+		GCC_ERROR((char*) glewGetString(err));
+		return false;
+	}
+
+	ImGui::CreateContext();
+	ImGuiIO& io = ImGui::GetIO(); (void)io;
+    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;     // Enable Keyboard Controls
+
+	// Setup Dear ImGui style
+    ImGui::StyleColorsDark();
+    //ImGui::StyleColorsLight();
+
+    // Setup scaling
+    float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
+    ImGuiStyle& style = ImGui::GetStyle();
+    style.ScaleAllSizes(main_scale);        // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
+    style.FontScaleDpi = main_scale;        // Set initial font scale. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
+
+    // Setup Platform/Renderer backends
+    ImGui_ImplSDL3_InitForOpenGL(m_Window, m_GlContext);
+    ImGui_ImplOpenGL3_Init(nullptr);
+
+	// TODO(munnellg) - implement this
+	// initialize the directory location you can store save game files
+	// _tcscpy_s(m_saveGameDirectory, GetSaveGameDirectory(GetHwnd(), VGetGameAppDirectory()));
+
+	if (GetRendererImpl() == Renderer_OpenGL46)
+	{
+		m_Renderer = std::shared_ptr<IRenderer>(GCC_NEW OpenGLRenderer46());
+	}
+	else
+	{
+		GCC_FATAL("Unknown renderer");
+	}
+	glEnable(GL_DEPTH_TEST);
+    glDepthFunc(GL_LESS);
+    
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	m_Renderer->VSetBackgroundColor(255, 20, 20, 200);
+	m_Renderer->VOnRestore();
+
+
+	// You usually must have an HWND to initialize your game views...
+	//    VCreateGameAndView			- Chapter 5, page 145
+	m_pGame = VCreateGameAndView();
+	if (!m_pGame)
+		return false;
+
+	// now that all the major systems are initialized, preload resources 
+	//    Preload calls are discussed in Chapter 5, page 148
+	m_ResCache->Preload("*.ogg", NULL);
+	m_ResCache->Preload("*.dds", NULL);
+	m_ResCache->Preload("*.jpg", NULL);
+
+	m_screenSize = Point(screenWidth, screenHeight);
+
+	m_bIsRunning = true;
+
+	return true;
+}
+
+bool GameCodeApp::VLoadGame(void)
+{
+    // Read the game options and see what the current game
+    // needs to be - all of the game graphics are initialized by now, too...
+	return m_pGame->VLoadGame(m_Options.m_Level.c_str());
+}
+
+int GameCodeApp::OnSysCommand(SDL_Event const &e)
+{
+	switch (e.type)
+	{
+		case SDL_EVENT_QUIT:
+		{
+			// The quit dialog confirmation would appear once for
+			// every SC_CLOSE we get - which happens multiple times
+			// if modal dialogs are up.  This now uses the g_QuitNoPrompt
+			// flag to only prompt when receiving a SC_CLOSE that isn't
+			// generated by us (identified by g_QuitNoPrompt).
+
+			// ET - 05/21/01 - Bug #1916 - Begin
+			// We were receiving multiple close dialogs
+			// when closing again ALT-F4 while the close
+			// confirmation dialog was up.
+			// Eat if already servicing a close
+			if (m_bQuitRequested)
+				return true;
+
+			// Wait for the application to be restored
+			// before going any further with the new 
+			// screen.  Flash until the person selects
+			// that they want to restore the game, then
+			// reinit the display if fullscreen.  
+			// The reinit is necessary otherwise the game
+			// will switch to windowed mode.
+
+			// Quit requested
+			m_bQuitRequested = true;
+			// Prompt
+			// TODO(munnellg): The book uses its own UI class for this. We should do the same
+			// int result = MessageBox(m_Window, "Are you sure you want to quit?", "Quit?", MB_YESNO);
+			// if (result == IDNO)
+			// {
+			// 	// Bail - quit aborted
+				
+			// 	// Reset quit requested flag
+			// 	m_bQuitRequested = false;
+				
+			// 	return true;
+			// }
+
+			m_bQuitting = true;
+
+			// Reset the quit after any other dialogs have popped up from this close
+			m_bQuitRequested = false;
+		}
+	}
+
+	return 0;
+}
+
+bool GameCodeApp::LoadStrings(std::string language)
+{
+	std::string languageFile = "Strings/";
+	languageFile += language;
+	languageFile += ".xml";
+
+	TiXmlElement* pRoot = XmlResourceLoader::LoadAndReturnRootXmlElement(languageFile.c_str());
+	if (!pRoot)
+	{
+		GCC_ERROR("Strings are missing.");
+		return false;
+	}
+
+	// Loop through each child element and load the component
+	for (TiXmlElement* pElem = pRoot->FirstChildElement(); pElem; pElem = pElem->NextSiblingElement())
+	{
+		const char *pKey=pElem->Attribute("id");
+		const char *pText=pElem->Attribute("value");
+		const char *pHotkey=pElem->Attribute("hotkey");
+
+		if (pKey && pText)
+		{
+			m_textResource[std::string(pKey)] = std::string(pText);
+
+			// TODO(munnellg) - maybe implement? Don't see what it's doing, but can look when SDL onboarded
+			// if (pHotKey)
+			// {
+			// 	m_hotkeys[std::string(wideKey)] = MapCharToKeycode(*pHotkey);
+			// }
+		}
+	}
+
+	return true;
+}
+
+//----------------------------------------------------------
+// GameCodeApp::GetString								- Chapter 5, page 144
+//
+// creates a string from a string resource ID in the string table
+// stored in a special DLL, LANG.DLL, so game text strings
+// can be language independant
+//
+std::string GameCodeApp::GetString(std::string sID)
+{
+	auto localizedString = m_textResource.find(sID);
+	if (localizedString == m_textResource.end())
+	{
+		GCC_ASSERT(0 && "String not found!");
+		return "";
+	}
+	return localizedString->second;
+}
+
+
+//----------------------------------------------------------
+// Win32 Specific Message Handlers
+//
+// WndProc - the main message handler for the window class
+//
+// OnNcCreate - this is where you can set window data before it is created
+// OnMove - called whenever the window moves; used to update members of g_App
+// OnDeviceChange - called whenever you eject the CD-ROM.
+// OnDisplayChange - called whenever the user changes the desktop settings
+// OnPowerBroadcast - called whenever a power message forces a shutdown
+// OnActivate - called whenever windows on the desktop change focus.
+//
+// Note: pUserContext added to comply with DirectX 9c - June 2005 Update
+//
+int GameCodeApp::MsgProc(SDL_Event &e)
+{
+	int result = ImGui_ImplSDL3_ProcessEvent(&e);
+	
+	ImGuiIO& io = ImGui::GetIO();
+
+	switch (e.type)
+	{
+		case SDL_EVENT_QUIT:
+		// case SDL_APP_TERMINATING:
+		// case SDL_APP_LOWMEMORY:
+		// case SDL_APP_WILLENTERBACKGROUND:
+		// case SDL_APP_DIDENTERBACKGROUND:
+		// case SDL_APP_WILLENTERFOREGROUND:
+		// case SDL_APP_DIDENTERFOREGROUND:
+		// case SDL_DISPLAYEVENT:
+		// case SDL_WINDOWEVENT:
+		// case SDL_SYSWMEVENT:
+			result = g_pApp->OnSysCommand(e);
+			break;
+		case SDL_EVENT_KEY_DOWN:
+        case SDL_EVENT_KEY_UP:
+        	if (io.WantCaptureKeyboard) 
+            {
+                break; 
+            }
+		case SDL_EVENT_MOUSE_MOTION:
+		case SDL_EVENT_MOUSE_BUTTON_DOWN:
+		case SDL_EVENT_MOUSE_BUTTON_UP:
+			if (io.WantCaptureMouse) 
+            {
+                break; 
+            }
+		case SDL_EVENT_JOYSTICK_BUTTON_DOWN:
+		case SDL_EVENT_JOYSTICK_BUTTON_UP:
+		case SDL_EVENT_JOYSTICK_AXIS_MOTION:
+		case SDL_EVENT_JOYSTICK_HAT_MOTION:
+		{
+			//
+			// See Chapter 10, page 278 for more explanation of this code.
+			//
+			if (g_pApp->m_pGame)
+			{
+				BaseGameLogic *pGame = g_pApp->m_pGame;
+				// Note the reverse order! User input is grabbed first from the view that is on top, 
+				// which is the last one in the list.
+				for(GameViewList::reverse_iterator i=pGame->m_gameViews.rbegin(); i!=pGame->m_gameViews.rend(); ++i)
+				{
+					if ( (*i)->VOnMsgProc( e ) )
+					{
+						result = true;
+						break;				// WARNING! This breaks out of the for loop.
+					}
+				}
+			}
+			break;
+		}
+	}
+
+	return 0;
+}
+
+GameCodeApp::Renderer GameCodeApp::GetRendererImpl()
+{
+	return Renderer_OpenGL46;
+}
+
+void GameCodeApp::RunMainLoop()
+{
+	Uint64 lastUpdate = SDL_GetTicks();
+	Uint64 lastDraw = SDL_GetTicks();
+	while (!m_bQuitting)
+	{
+		// process any inputs
+		PumpSDLEvents();
+
+		OnUpdateGame((float) SDL_GetTicks(), ((float) (SDL_GetTicks() - lastUpdate)) / 1000.0f);
+		lastUpdate = SDL_GetTicks();
+
+		// render the frame
+		OnOpenGLFrameRender((float) SDL_GetTicks(), ((float) (SDL_GetTicks() - lastDraw)) / 1000.0f);
+		lastDraw = SDL_GetTicks();
+	}
+}
+
+void GameCodeApp::Shutdown()
+{
+	// TODO(munnellg): release assets and shut down gracefully
+}
+
+void GameCodeApp::PumpSDLEvents()
+{
+	SDL_Event e;
+
+	while (SDL_PollEvent(&e))
+	{
+		MsgProc(e);
+	}
+}
+
+
+
+
+
+//--------------------------------------------------------------------------------------
+// This callback function will be called once at the beginning of every frame. This is the
+// best location for your application to handle updates to the scene, but is not 
+// intended to contain actual rendering calls, which should instead be placed in the 
+// OnFrameRender callback.  
+//
+// See Game Coding Complete - 4th Edition - Chapter X, page Y
+//--------------------------------------------------------------------------------------
+void GameCodeApp::OnUpdateGame(double fTime, float fElapsedTime)
+{
+	// if (g_pApp->HasModalDialog())
+	// {	
+	// 	// don't update the game if a modal dialog is up.
+	// 	return;
+	// }
+
+	// if (g_pApp->m_bQuitting)
+	// {
+	// 	PostMessage(g_pApp->GetHwnd(), WM_CLOSE, 0, 0);
+	// }
+
+	if (g_pApp->m_pGame)
+	{
+        IEventManager::Get()->VUpdate(20); // allow event queue to process for up to 20 ms
+
+		// if (g_pApp->m_pBaseSocketManager)
+			// g_pApp->m_pBaseSocketManager->DoSelect(0);	// pause 0 microseconds
+		g_pApp->m_pGame->VOnUpdate(float(fTime), fElapsedTime);
+	}
+}
+
+
+
+
+
+
+void GameCodeApp::OnOpenGLFrameRender(double fTime, float fElapsedTime)
+{
+	static uint64_t lastDraw = 0;
+	uint64_t currTick = SDL_GetTicks();
+	
+	if (currTick == lastDraw)
+		return;
+
+	// if (currTick - lastDraw > SCREEN_REFRESH_RATE)
+	// {
+		g_pApp->m_Renderer->VPreRender();
+
+		BaseGameLogic *pGame = g_pApp->m_pGame;
+
+		for (GameViewList::iterator i = pGame->m_gameViews.begin(),
+				end = pGame->m_gameViews.end(); i!=end; ++i)
+		{
+			(*i)->VOnRender(fTime, fElapsedTime);
+		}
+
+		g_pApp->m_pGame->VRenderDiagnostics();
+
+		g_pApp->m_Renderer->VPostRender();
+
+		// record the last successful paint
+		lastDraw = currTick;
+	// }
+}

+ 159 - 0
Source/GCC4/GameCode4/GameCode.h

@@ -0,0 +1,159 @@
+#pragma once
+//========================================================================
+// GameCode.h : Defines the entry point for the application.
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Mainloop/Initialization.h"
+#include "../Debugging/Logger.h"
+#include "BaseGameLogic.h"
+#include <SDL3/SDL.h>
+
+class EventManager;
+
+//
+// class GameCodeApp							- Chapter X, page Y
+//
+class GameCodeApp
+{
+	friend class OpenGLRenderer46;
+	friend class LogMgr;
+protected:
+	SDL_Window *m_Window;
+	SDL_Renderer *m_SdlRenderer;
+	SDL_GLContext m_GlContext;
+	bool m_bIsRunning;						// true if everything is initialized and the game is in the main loop
+	bool m_bQuitRequested;					// true if the app should run the exit sequence
+	bool m_bQuitting;						// true if the app is running the exit sequence
+	Point m_screenSize;						// game screen size
+	bool m_bIsEditorRunning;				// true if the game editor is running
+
+public:
+	const Point &GetScreenSize() { return m_screenSize; }
+
+protected:
+	std::map<std::string,std::string> m_textResource;
+	std::map<std::string,unsigned int> m_hotkeys;
+
+public:
+
+	GameCodeApp();
+
+	// Game Application Data
+	// You must define these in an inherited
+	// class - see TeapotWarsApp for an example
+	// TODO(munnellg): uncomment and implement
+	virtual std::string VGetGameTitle()=0;
+	// virtual TCHAR *VGetGameAppDirectory()=0;
+	// virtual SDL_Surface* VGetIcon()=0;
+
+	SDL_Window* GetWindow() { return m_Window; }
+
+	static int MsgProc(SDL_Event &e);
+
+	// TODO(munnellg): uncomment and implement
+	// int OnDisplayChange(int colorDepth, int width, int height);
+	// int OnPowerBroadcast(int event);
+	int OnSysCommand(SDL_Event const &e);
+	// int OnClose();
+
+	// TODO(munnellg): uncomment and implement
+	// Game Application actions
+	// int OnAltEnter();
+	// int OnNcCreate(LPCREATESTRUCT cs);
+
+	bool LoadStrings(std::string language);
+	std::string GetString(std::string sID);
+
+	virtual bool InitInstance(/*HINSTANCE hInstance, LPWSTR lpCmdLine, HWND hWnd = NULL, */int screenWidth = SCREEN_WIDTH, int screenHeight = SCREEN_HEIGHT);
+
+	// FUTURE WORK - Seems like this class could be refactored, especailly the renderer !
+
+	enum Renderer
+	{
+		Renderer_Unknown,
+		Renderer_OpenGL46,
+	};
+
+	std::shared_ptr<IRenderer> m_Renderer;
+
+	static Renderer GetRendererImpl();
+
+	// OpenGL 4.6 Specific Stuff
+	// static bool CALLBACK IsD3D11DeviceAcceptable( const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo, DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext );
+	// static HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
+	// static HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );
+	// static void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext );
+	// static void CALLBACK OnD3D11DestroyDevice( void* pUserContext );
+	static void OnOpenGLFrameRender(double fTime, float fElapsedTime);
+
+	static void OnUpdateGame(double fTime, float fElapsedTime);
+
+	// GameCode Specific Stuff
+	BaseGameLogic *m_pGame;
+	struct GameOptions m_Options;
+	
+	// You must define these functions to initialize your game.
+	// Look for them in TeapotWars.h and TeapotWars.cpp
+	virtual BaseGameLogic *VCreateGameAndView()=0;
+	virtual bool VLoadGame(void);
+	// HumanView* GetHumanView();				// Added post press - it was convenient to grab the HumanView attached to the game.
+
+	// File and Resource System
+	class ResCache *m_ResCache;
+
+	// Event manager
+	EventManager *m_pEventManager;
+	
+public:
+	// [gmunnelly] added for SDL/OpenGL compatibility. We must own the main loop
+	void RunMainLoop();
+	void Shutdown();
+	void PumpSDLEvents();
+	
+	// Main loop processing
+	void AbortGame() { m_bQuitting = true; }
+	// TODO(munnellg): get proper exit code
+	int GetExitCode() { return 0; }
+	bool IsRunning() { return m_bIsRunning; }
+	void SetQuitting(bool quitting) { m_bQuitting = quitting; }
+
+	BaseGameLogic* GetGameLogic(void) const { return m_pGame; }
+	
+};
+
+
+extern GameCodeApp *g_pApp;

+ 77 - 0
Source/GCC4/GameCode4/GameCode4.cpp

@@ -0,0 +1,77 @@
+//========================================================================
+// GameCode4.cpp - the entry point for the GameCode4 engine
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "GameCode.h"
+#include "../Debugging/Logger.h"
+
+
+//--------------------------------------------------------------------------------------
+// Entry point to the program. Initializes everything and goes into a message processing 
+// loop. Idle time is used to render the scene.
+//
+// See Game Coding Complete 4th Edition - Chapter 5, page 134
+//--------------------------------------------------------------------------------------
+
+int GameCode4(int argc, char **argv)
+{
+	// [rez] Initialize the logging system as the very first thing you ever do!
+    // [mrmike] LOL after the memory system flags are set, that is!
+	Logger::Init("Logging.xml");
+
+	g_pApp->m_Options.Init("PlayerOptions.xml");
+
+	// Perform application initialization
+	if (!g_pApp->InitInstance(g_pApp->m_Options.m_ScreenSize.x, g_pApp->m_Options.m_ScreenSize.y))
+	{
+		// [rez] Note: Fix memory leaks if we hit this branch.  Also, print an error.
+		return false;
+	}
+
+
+	// Pass control to the sample framework for handling the message pump and 
+    // dispatching render calls. The sample framework will call your FrameMove 
+    // and FrameRender callback when there is idle time between handling window messages.
+
+    g_pApp->RunMainLoop();
+    g_pApp->Shutdown();
+
+    // [rez] Destroy the logging system at the last possible moment
+	Logger::Destroy();
+	
+	return g_pApp->GetExitCode();
+}

+ 327 - 0
Source/GCC4/GameCode4/interfaces.h

@@ -0,0 +1,327 @@
+#pragma once
+//========================================================================
+// Interfaces.h : Defines interface classes defined throughout the book
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Graphics3D/Geometry.h"
+#include "../Utilities/types.h"
+
+#include <memory>
+#include <list>
+#include <optional>
+#include <SDL3/SDL.h>
+
+class Actor;
+class ActorComponent;
+
+typedef unsigned int ActorId;
+typedef unsigned int ComponentId;
+
+const ActorId INVALID_ACTOR_ID = 0;
+const ComponentId INVALID_COMPONENT_ID = 0;
+
+typedef std::shared_ptr<Actor> StrongActorPtr;
+typedef std::weak_ptr<Actor> WeakActorPtr;
+typedef std::shared_ptr<ActorComponent> StrongActorComponentPtr;
+typedef std::weak_ptr<ActorComponent> WeakActorComponentPtr;
+
+template<class T>
+struct SortBy_SharedPtr_Content
+{
+    bool operator()(const std::shared_ptr<T> &lhs, const std::shared_ptr<T> &rhs) const
+        { return *lhs < *rhs; }
+};
+
+//
+// class IScreenElement							- Chapter 10, page 285
+//
+class IScreenElement
+{
+public:
+	virtual int VOnRestore() = 0;
+	// virtual int VOnLostDevice() = 0;
+	virtual int VOnRender(double fTime, float fElapsedTime) = 0;
+	virtual void VOnUpdate(int deltaMilliseconds) = 0;
+
+	virtual int VGetZOrder() const = 0;
+	virtual void VSetZOrder(int const zOrder) = 0;
+	virtual bool VIsVisible() const = 0;
+	virtual void VSetVisible(bool visible) = 0;
+
+	virtual int VOnMsgProc( SDL_Event &e )=0;
+
+	virtual ~IScreenElement() { };
+	virtual bool const operator <(IScreenElement const &other) { return VGetZOrder() < other.VGetZOrder(); }
+};
+
+class IGamePhysics;
+
+class IGameLogic
+{
+public:
+	// virtual WeakActorPtr VGetActor(const ActorId id)=0;
+	// virtual StrongActorPtr VCreateActor(const std::string &actorResource, TiXmlElement *overrides, const glm::mat4 *initialTransform=NULL, const ActorId serversActorId=INVALID_ACTOR_ID)=0;
+	// virtual void VDestroyActor(const ActorId actorId)=0;
+	virtual bool VLoadGame(const char* levelResource)=0;
+	virtual void VSetProxy()=0;				
+	virtual void VOnUpdate(float time, float elapsedTime)=0;
+	// virtual void VChangeState(enum BaseGameState newState)=0;
+	// virtual void VMoveActor(const ActorId id, glm::mat4 const &mat)=0;
+	// virtual shared_ptr<IGamePhysics> VGetGamePhysics(void) = 0;
+};
+
+enum GameViewType
+{
+	GameView_Human,
+	GameView_Remote,
+	GameView_AI,
+	GameView_Recorder,
+	GameView_Other
+};
+
+typedef unsigned int GameViewId;
+extern const GameViewId gc_InvalidGameViewId;
+
+class IGameView 
+{
+public:
+	virtual int VOnRestore()=0;
+	virtual void VOnRender(double fTime, float fElapsedTime)=0;
+	// virtual HRESULT VOnLostDevice()=0;
+	virtual GameViewType VGetType()=0;
+	virtual GameViewId VGetId() const=0;
+	virtual void VOnAttach(GameViewId vid, ActorId aid)=0;
+
+	virtual int VOnMsgProc( SDL_Event &e )=0;
+	virtual void VOnUpdate(unsigned long deltaMs)=0;
+
+	virtual ~IGameView() { };
+};
+
+typedef std::list<std::shared_ptr<IScreenElement> > ScreenElementList;
+typedef std::list<std::shared_ptr<IGameView>> GameViewList;
+
+
+////////////////////////////////////////////////////
+//
+// IKeyboardHandler Description		- Chapter 9, page 242
+// IPointerHandler Description		- Chapter 9, page 242
+// IJoystickHandler Description		- Chapter 9, page 242
+// IGamepadHandler Description		- Chapter 9, page 242
+//
+// These are the public APIs for any object that implements reactions
+// to events sent by hardware user interface devices.
+//
+// Note: IJoystickHandler and IGamepadHandler are not currently
+//       implemented anywhere in the codebase. They are here
+//       as examples, and could require modification to actually work!
+//
+////////////////////////////////////////////////////
+
+class IKeyboardHandler
+{
+public:
+	virtual bool VOnKeyDown(const unsigned char c) = 0;
+	virtual bool VOnKeyUp(const unsigned char c) = 0;
+};
+
+class IPointerHandler
+{
+public:
+	virtual bool VOnPointerMove(const Point &pos, const int radius) = 0;
+	virtual bool VOnPointerButtonDown(const Point &pos, const int radius, const std::string &buttonName) = 0;
+	virtual bool VOnPointerButtonUp(const Point &pos, const int radius, const std::string &buttonName) = 0;
+};
+
+class IJoystickHandler
+{
+	virtual bool VOnButtonDown(const std::string &buttonName, int const pressure) = 0;
+	virtual bool VOnButtonUp(const std::string &buttonName) = 0;
+	virtual bool VOnJoystick(float const x, float const y) = 0;
+};
+
+class IGamepadHandler
+{
+	virtual bool VOnTrigger(const std::string &triggerName, float const pressure)=0;
+	virtual bool VOnButtonDown(const std::string &buttonName, int const pressure)=0;
+	virtual bool VOnButtonUp(const std::string &buttonName)=0;
+	virtual bool VOnDirectionalPad(const std::string &direction)=0;
+	virtual bool VOnThumbstick(const std::string &stickName, float const x, float const y)=0;
+};
+
+////////////////////////////////////////////////////
+//
+// class IResourceFile						- Chapter 8, page 222
+// The core of a resource cache system
+// 
+////////////////////////////////////////////////////
+
+class Resource;
+class IResourceFile;
+class ResHandle;
+
+//
+// class IResourceLoader					- Chapter 8, page 224
+//
+class IResourceLoader
+{
+public:
+	virtual std::string VGetPattern()=0;
+	virtual bool VUseRawFile()=0;
+	virtual bool VDiscardRawBufferAfterLoad()=0;
+	virtual bool VAddNullZero() { return false; }
+	virtual unsigned int VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize)=0;
+	virtual bool VLoadResource(char *rawBuffer, unsigned int rawSize, std::shared_ptr<ResHandle> handle)=0;
+};
+
+class IResourceFile
+{
+public:
+	virtual bool VOpen()=0;
+	virtual int VGetRawResourceSize(const Resource &r)=0;
+	virtual int VGetRawResource(const Resource &r, char *buffer)=0;
+	virtual int VGetNumResources() const = 0;
+	virtual std::string VGetResourceName(int num) const = 0;
+	virtual bool VIsUsingDevelopmentDirectories(void) const = 0;
+	virtual ~IResourceFile() { }
+};
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// enum RenderPass							- Chapter 16, page 529
+//
+//   3D scenes are drawn in passes - this enum defines the render passes
+//   supported by the 3D scene graph created by class Scene.
+/////////////////////////////////////////////////////////////////////////////
+
+enum RenderPass
+{
+	RenderPass_0,
+	RenderPass_Static = RenderPass_0,
+	RenderPass_Actor,
+	RenderPass_Sky,
+	RenderPass_NotRendered,
+	RenderPass_Last
+};
+
+
+
+
+class Scene;
+class SceneNodeProperties;
+// class RayCast;
+class LightNode;
+
+typedef std::list<std::shared_ptr<LightNode> > Lights;
+
+
+class IRenderState
+{
+public:
+	virtual std::string VToString()=0;
+};
+
+//
+// class IRenderer				- not described in the 4th edition
+//
+// class IRenderer abstracts the renderer implementation so the engine
+//   can use D3D9 or D3D11.
+//
+class IRenderer
+{
+public:
+	virtual void VSetBackgroundColor(unsigned char bgA, unsigned char bgR, unsigned char bgG, unsigned char bgB)=0; 
+	virtual int VOnRestore()=0;
+	virtual void VShutdown()=0;
+	virtual bool VPreRender()=0;
+	virtual bool VPostRender()=0;
+	virtual void VCalcLighting(Lights *lights, int maximumLights)=0;
+	virtual void VSetWorldTransform(const glm::mat4 m)=0;
+	virtual void VSetViewTransform(const glm::mat4 m)=0;
+	virtual void VSetProjectionTransform(const glm::mat4 m)=0;
+	virtual std::shared_ptr<IRenderState> VPrepareAlphaPass()=0;
+	virtual std::shared_ptr<IRenderState> VPrepareSkyBoxPass()=0;
+	// virtual void VDrawLine(const Vec3& from,const Vec3& to,const Color& color)=0;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// class ISceneNode					- Chapter 16, page 524
+//
+//   This is the public interface for nodes in a 3D scene graph.
+/////////////////////////////////////////////////////////////////////////////
+
+class ISceneNode
+{
+public:
+	virtual const SceneNodeProperties * const VGet() const=0;
+
+	virtual void VSetTransform(const glm::mat4 toWorld, std::optional<const glm::mat4> fromWorld=std::nullopt)=0;
+
+	virtual int VOnUpdate(Scene *pScene, uint64_t const elapsedMs)=0;
+	virtual int VOnRestore(Scene *pScene)=0;
+
+	virtual int VPreRender(Scene *pScene)=0;
+	virtual bool VIsVisible(Scene *pScene) const=0;
+	virtual int VRender(Scene *pScene)=0;
+	virtual int VRenderChildren(Scene *pScene)=0;
+	virtual int VPostRender(Scene *pScene)=0;
+
+	virtual bool VAddChild(std::shared_ptr<ISceneNode> kid)=0;
+	virtual bool VRemoveChild(ActorId id)=0;
+	// virtual HRESULT VOnLostDevice(Scene *pScene)=0;
+	// virtual HRESULT VPick(Scene *pScene, RayCast *pRayCast)=0;
+
+
+	virtual ~ISceneNode() { };
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// IScriptManager Description
+//
+//   This is the public interface for the scripting system.
+/////////////////////////////////////////////////////////////////////////////
+class IScriptManager
+{
+public:
+    virtual ~IScriptManager(void) {}
+    virtual bool VInit(void) = 0;
+    virtual void VExecuteFile(const char* resource) = 0;
+    virtual void VExecuteString(const char* str) = 0;
+};
+

+ 91 - 0
Source/GCC4/Graphics3D/Geometry.cpp

@@ -0,0 +1,91 @@
+//========================================================================
+// Geometry.cpp : Collection of code for 3D math and 3D shapes
+//
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+#include "Geometry.h"
+
+Frustum::Frustum()
+{
+	m_Fov = GCC_PI/4.0f;	// default field of view is 90 degrees
+	m_Aspect = 1.0f;		// default aspect ratio is 1:1
+	m_Near = 1.0f;			// default near clip plane is 1m away from the camera
+	m_Far = 100.0f;			// default far clip plane is 100m away from the camera
+}
+
+
+//
+// Frustum::Inside					- Chapter 14, page 477
+//
+bool Frustum::Inside(const glm::vec3 &point) const
+{
+	// TODO - implement
+	return false;
+}
+
+
+//
+// Frustum::Inside					- Chapter 14, page 477
+//
+bool Frustum::Inside(const glm::vec3 &point, const float radius) const
+{
+	// TODO - implement
+	return false;
+}
+
+//
+// Frustum::Init					- Chapter 14, page 477
+//
+void Frustum::Init(const float fov, const float aspect, const float nearClip, const float farClip)
+{
+	m_Fov = fov;
+	m_Aspect = aspect;
+	m_Near = nearClip;
+	m_Far = farClip;
+
+	// TODO - generate frustum mesh so we can render for debugging
+}
+
+
+//
+// Frustum::Render					- not described in the 4th edition
+//
+void Frustum::Render()
+{
+	// TODO - implement
+}

+ 245 - 0
Source/GCC4/Graphics3D/Geometry.h

@@ -0,0 +1,245 @@
+#pragma once
+//========================================================================
+// Geometry.h : Collection of code for 3D math and 3D shapes
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+//========================================================================
+//  Content References in Game Coding Complete 3rd Edition
+// 
+//  class glm::vec3				- Chapter 14, page 456
+//  class Vec4				- Chapter 14, page 457
+//  class Mat4x4			- Chapter 14, page 466
+//  class Quaternion		- Chapter 14, page 471
+//  class Plane				- Chapter 14, page 473
+//  class Frustum			- Chapter 14, page 474
+//
+
+#include <cmath>
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+
+#include <iostream>
+#include <glm/gtx/string_cast.hpp>
+
+const float  GCC_PI = 3.14159265358979f;
+const float  GCC_2PI = 2 * GCC_PI;
+
+extern glm::vec3 g_Up;
+extern glm::vec3 g_Right;
+extern glm::vec3 g_Forward;
+
+extern glm::vec4 g_Up4;
+extern glm::vec4 g_Right4;
+extern glm::vec4 g_Forward4;
+
+namespace geometry
+{
+	inline glm::vec3 GetPosition(glm::mat4 matrix)
+	{
+		return glm::vec3(matrix[3]);
+	}
+
+	inline void SetPosition(glm::mat4 &matrix, glm::vec3 position)
+	{
+		matrix[3] = glm::vec4(position, matrix[3].w);
+	}
+
+	inline glm::vec3 GetDirection(glm::mat4 m)
+	{
+		// zero out position so we just have rotation component
+		SetPosition(m, glm::vec3(0.0f));
+		glm::vec4 forward = m * g_Forward4;
+		return glm::vec3(forward);
+	}
+
+	inline glm::mat4 BuildRotationX(float const radians)
+	{
+		return glm::rotate(glm::mat4(1.0f), radians, glm::vec3(1.0f, 0.0f, 0.0f));
+	}
+
+	inline glm::mat4 BuildRotationY(float const radians)
+	{
+		return glm::rotate(glm::mat4(1.0f), radians, glm::vec3(0.0f, 1.0f, 0.0f));
+	}
+
+	inline glm::mat4 BuildRotationZ(float const radians)
+	{
+		return glm::rotate(glm::mat4(1.0f), radians, glm::vec3(0.0f, 0.0f, 1.0f));
+	}
+
+	inline glm::mat4 BuildTranslation(glm::vec3 const translation)
+	{
+		return glm::translate(glm::mat4(1.0f), translation);
+	}
+
+	inline glm::mat4 BuildYawPitchRoll(float const yawRadians, float const pitchRadians, float const rollRadians)
+	{
+		// [munnellg] taken from page 277 of 3d math primer for graphics and game development
+		float cy = cos(yawRadians);
+		float sy = sin(yawRadians);
+		float cp = cos(pitchRadians);
+		float sp = sin(pitchRadians);
+		float cr = cos(rollRadians);
+		float sr = sin(rollRadians);
+		
+		glm::mat4 rotation = glm::mat4(
+			 cy * cr + sy * sp * sr, sr * cp, -sy * cr + cy * sp * sr, 0.0f,
+			-cy * sr + sy * sp * cr, cr * cp,  sr * sy + cy * sp * cr, 0.0f,
+			                sy * cp,     -sp,                 cy * cp, 0.0f,
+			                      0,       0,                       0, 1.0f
+		);
+		return rotation;
+	}
+
+	inline glm::vec3 GetYawPitchRoll(const glm::mat4 &orientation)
+	{
+		float yaw, pitch, roll;
+
+		pitch = std::asin(-orientation[2][1]);
+
+		double threshold = 0.001; // Hardcoded constant - burn him, he's a witch
+		double test = std::cos(pitch);
+		
+		if (test > threshold)
+		{
+			roll = std::atan2(orientation[0][1], orientation[1][1]);
+			yaw = std::atan2(orientation[2][0], orientation[2][2]);
+		}
+		else
+		{
+			roll = std::atan2(-orientation[1][0], orientation[0][0]);
+			yaw = 0.0f;	
+		}
+
+		return glm::vec3(yaw, pitch, roll);
+	}
+};
+
+
+////////////////////////////////////////////////////
+//
+// D3D9 Vertex Type Definitions
+//
+//  TRANSFORMED_VERTEX Description
+//  UNTRANSFORMED_VERTEX Description
+//  UNTRANSFORMED_LIT_VERTEX Description
+//  D3D9Vertex_UnlitColored Description
+//  D3D9Vertex_ColoredTextured Description
+//  D3D9Vertex_Colored Description
+//
+//  Note: There's been a slight change from the book in this code.
+//        Instead of #define D3DFVF_BlahBlah they are static constants;
+//        find them at the top of Geometry.cpp
+//
+// See Game Coding Complete, 3rd Edition, Chapter 13, page 440-444
+////////////////////////////////////////////////////
+
+struct SimpleVertex
+{
+	glm::vec3 Pos;
+	glm::vec3 Normal;
+};
+
+struct VertexUnlitTextured
+{
+	glm::vec3 Pos;
+	glm::vec3 Normal;
+	glm::vec2 Uv;
+};
+
+struct VertexUnlitTexturedColored
+{
+	glm::vec3 Pos;
+	glm::vec3 Normal;
+	glm::vec3 Diffuse;
+	glm::vec2 Uv;
+};
+
+struct VertexPositionColored
+{
+	glm::vec3 Pos;
+	glm::vec3 Diffuse;
+};
+
+////////////////////////////////////////////////////
+//
+// Plane Definition
+//
+////////////////////////////////////////////////////
+
+
+class Plane
+{
+
+};
+
+
+
+////////////////////////////////////////////////////
+//
+// Frustum Definition
+//
+////////////////////////////////////////////////////
+
+class Frustum
+{
+public:
+	enum Side { Near, Far, Top, Right, Bottom, Left, NumPlanes };
+
+	Plane m_Planes[NumPlanes];	// planes of the frustum in camera space
+	glm::vec3 m_NearClip[4];	// verts of the near clip planes in camera space
+	glm::vec3 m_FarClip[4];		// verts of the far clip plane in camera space
+
+	float m_Fov;				// field of view in radians
+	float m_Aspect;				// aspect ratio - width divided by height
+	float m_Near;				// near clipping distance
+	float m_Far;				// far clipping distance
+
+public:
+	Frustum();
+
+	bool Inside(const glm::vec3 &point) const;
+	bool Inside(const glm::vec3 &point, const float radius) const;
+	const Plane &Get(Side side) { return m_Planes[side]; }
+	void SetFOV(float fov) { m_Fov=fov; Init(m_Fov, m_Aspect, m_Near, m_Far); }
+	void SetAspect(float aspect) { m_Aspect=aspect; Init(m_Fov, m_Aspect, m_Near, m_Far); }
+	void SetNear(float near) { m_Near=near; Init(m_Fov, m_Aspect, m_Near, m_Far); }
+	void SetFar(float far) { m_Far=far; Init(m_Fov, m_Aspect, m_Near, m_Far); }
+	void Init(const float fov, const float aspect, const float near, const float far);
+
+	void Render();
+};

+ 94 - 0
Source/GCC4/Graphics3D/Lights.cpp

@@ -0,0 +1,94 @@
+//========================================================================
+// Lights.h - implements a simple light class for the GameCode4 scene graph
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+
+#include "../GameCode4/GameCode.h"
+#include "../Actors/RenderComponent.h"
+#include "Lights.h"
+
+LightNode::LightNode(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, const LightProperties &props, const glm::mat4 t)
+	: SceneNode(actorId, renderComponent, RenderPass_NotRendered, t)
+{
+	m_LightProps = props;
+}
+
+int OpenGLLightNode46::VOnUpdate(Scene*, uint64_t const elapsedMs)
+{
+	// light color can change anytime! Check the BaseRenderComponent!
+	LightRenderComponent* lrc = static_cast<LightRenderComponent*>(m_RenderComponent);
+	m_Props.GetMaterial().SetDiffuse(lrc->GetColor());
+	return 0;
+}
+
+void LightManager::CalcLighting(Scene *pScene)
+{
+	// FUTURE WORK: There might be all kinds of things you'd want to do here for optimization, especially turning off lights on actors that can't be seen, etc.
+	pScene->GetRenderer()->VCalcLighting(&m_Lights, MAXIMUM_LIGHTS_SUPPORTED);
+
+	int count = 0;
+
+	GCC_ASSERT(m_Lights.size() < MAXIMUM_LIGHTS_SUPPORTED);
+	for (Lights::iterator i=m_Lights.begin(); i!=m_Lights.end(); ++i, ++count)
+	{
+		std::shared_ptr<LightNode> light = *i;
+
+		if (count==0)
+		{
+			// Light 0 is the only one we use for ambient lighting. The rest are ignored in the simple shaders used for GameCode4.
+			Color ambient = light->VGet()->GetMaterial().GetAmbient();
+			m_vLightAmbient = glm::vec4(ambient.r, ambient.g, ambient.b, 1.0f);
+		}
+
+		glm::vec3 lightDir = light->GetDirection();
+		m_vLightDir[count] = glm::vec4(lightDir.x, lightDir.y, lightDir.z, 1.0f);		
+		m_vLightDiffuse[count] = light->VGet()->GetMaterial().GetDiffuse();
+	}	
+}
+
+void LightManager::CalcLighting(ConstantBuffer_Lighting* pLighting, SceneNode* pNode)
+{
+	int count = GetLightCount(pNode);
+	if (count)
+	{
+		pLighting->m_vLightAmbient = *GetLightAmbient(pNode);
+		memcpy(pLighting->m_vLightDir, GetLightDirection(pNode), sizeof(glm::vec4) * count);
+		memcpy(pLighting->m_vLightDiffuse, GetLightDiffuse(pNode), sizeof(glm::vec4) * count);
+		pLighting->m_nNumLights = count;
+	}
+}

+ 131 - 0
Source/GCC4/Graphics3D/Lights.h

@@ -0,0 +1,131 @@
+#pragma once
+//========================================================================
+// Lights.h - implements a simple light class for the GameCode4 scene graph
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "OpenGLRenderer.h"
+#include "Geometry.h"
+#include "Scene.h"
+#include "SceneNodes.h"
+
+// Note: Light color is stored in the Material structure, which is already present in all SceneNodes.
+
+//
+// struct LightProperties				- Chapter 16, page 551
+//
+struct LightProperties
+{
+	float	m_Attenuation[3]; /* Attenuation coefficients */
+	float	m_Range;
+	float	m_Falloff;
+	float	m_Theta;
+	float	m_Phi;
+};
+
+//
+// class LightNode						- Chapter 16, page 551
+//
+//    Note: In the book this class implements the LightNode in D3D11, but here it is a base
+//    class. The derived classes make it possible to run the engine in D3D9 or D3D11.
+//
+class LightNode : public SceneNode
+{
+protected:
+	LightProperties m_LightProps;
+
+public:
+	LightNode(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, const LightProperties &props, glm::mat4 t);
+};
+
+
+// class D3DLightNode9 : public LightNode
+// {
+// public:
+// 	D3DLightNode9(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, const LightProperties &lightProps, const Mat4x4 *t)
+// 		: LightNode(actorId, renderComponent, lightProps,  t) { }
+
+// 	D3DLIGHT9	m_d3dLight9;
+
+// 	virtual HRESULT VOnRestore(Scene *pScene);
+// 	virtual HRESULT VOnUpdate(Scene *, DWORD const elapsedMs);
+// };
+
+
+// class D3DLightNode11 : public LightNode
+// {
+// public:
+// 	D3DLightNode11(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent,  const LightProperties &lightProps, const Mat4x4 *t)
+// 		: LightNode(actorId, renderComponent, lightProps,  t) { }
+
+// 	virtual HRESULT VOnRestore() { return S_OK; };
+// 	virtual HRESULT VOnUpdate(Scene *, DWORD const elapsedMs);
+// };
+
+class OpenGLLightNode46 : public LightNode
+{
+public:
+	OpenGLLightNode46(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, const LightProperties &lightProps, const glm::mat4 t)
+		: LightNode(actorId, renderComponent, lightProps, t) { }
+
+	virtual int VOnRestore(Scene *pScene) { return 0; }
+	virtual int VOnUpdate(Scene *, uint64_t const elapsedMs);
+};
+
+
+struct ConstantBuffer_Lighting;
+
+
+//
+// class LightManager					- Chapter 16, 553
+//
+class LightManager
+{
+	friend class Scene;
+
+protected:
+	Lights					m_Lights;
+	glm::vec4				m_vLightDir[MAXIMUM_LIGHTS_SUPPORTED];
+	Color 					m_vLightDiffuse[MAXIMUM_LIGHTS_SUPPORTED];
+	glm::vec4				m_vLightAmbient;
+public:
+	void CalcLighting(Scene *pScene);
+	void CalcLighting(ConstantBuffer_Lighting* pLighting, SceneNode* pNode);
+	int GetLightCount(const SceneNode *node) { return m_Lights.size(); }
+	const glm::vec4 *GetLightAmbient(const SceneNode *node) { return &m_vLightAmbient; }
+	const glm::vec4 *GetLightDirection(const SceneNode *node) { return m_vLightDir; }
+	const Color *GetLightDiffuse(const SceneNode *node) { return m_vLightDiffuse; }
+};

+ 192 - 0
Source/GCC4/Graphics3D/Material.cpp

@@ -0,0 +1,192 @@
+//========================================================================
+// File: Material.cpp - stores texture and material information for D3D9 and D3D11
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "Material.h"
+#include <SDL3_image/SDL_image.h>
+
+////////////////////////////////////////////////////
+// class Material						- Chapter 14, page 486
+////////////////////////////////////////////////////
+
+Material::Material()
+{
+	m_Diffuse  = g_White;
+	m_Ambient  = Color(0.10f, 0.10f, 0.10f, 1.0f);
+	m_Specular = g_White;
+	m_Emissive = g_Black;
+	m_Power    = 0;
+}
+
+void Material::SetAmbient(const Color &color)
+{
+	m_Ambient = color;
+}
+
+void Material::SetDiffuse(const Color &color)
+{
+	m_Diffuse = color;
+}
+
+void Material::SetSpecular(const Color &color, const float power)
+{
+	m_Specular = color;
+	m_Power    = power;
+}
+
+void Material::SetEmissive(const Color &color)
+{
+	m_Emissive = color;
+}
+
+void Material::SetAlpha(const float alpha)
+{
+	m_Diffuse.a = alpha;
+}
+
+void Material::D3Use9()
+{
+	// [munnellg] noop on linux
+	// DXUTGetD3D9Device()->SetMaterial( &m_D3DMaterial );	
+}
+
+//
+// class DdsResourceLoader					- creates an interface with the Resource cache to load DDS files
+//
+class DdsResourceLoader : public TextureResourceLoader
+{
+public:
+	virtual std::string VGetPattern() { return "*.dds"; }
+};
+
+std::shared_ptr<IResourceLoader> CreateDDSResourceLoader()
+{
+	return std::shared_ptr<IResourceLoader>(GCC_NEW DdsResourceLoader());
+}
+
+//
+// class JpgResourceLoader					- creates an interface with the Resource cache to load JPG files
+//
+class JpgResourceLoader : public TextureResourceLoader
+{
+public:
+	virtual std::string VGetPattern() { return "*.jpg"; }
+};
+
+std::shared_ptr<IResourceLoader> CreateJPGResourceLoader()
+{
+	return std::shared_ptr<IResourceLoader>(GCC_NEW JpgResourceLoader());
+}
+
+OpenGLTextureResourceExtraData::OpenGLTextureResourceExtraData()
+	: m_texture_id(0)
+{
+}
+
+OpenGLTextureResourceExtraData::~OpenGLTextureResourceExtraData()
+{
+	glDeleteTextures(1, &m_texture_id);	
+}
+
+unsigned int TextureResourceLoader::VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize)
+{
+	// This will keep the resource cache from allocating memory for the texture, so DirectX / OpenGL can manage it on it's own.
+	return 0;
+}
+
+bool TextureResourceLoader::VLoadResource(char *rawBuffer, unsigned int rawSize, std::shared_ptr<ResHandle> handle)
+{
+	std::shared_ptr<OpenGLTextureResourceExtraData> extra = std::shared_ptr<OpenGLTextureResourceExtraData>(GCC_NEW OpenGLTextureResourceExtraData);
+	
+	SDL_IOStream* rw = SDL_IOFromConstMem(rawBuffer, rawSize);
+	if (!rw)
+	{
+		GCC_ERROR(SDL_GetError());
+		return false;
+	}
+
+	SDL_Surface *surface = IMG_Load_IO(rw, 0);
+	if (!surface) {
+		GCC_ERROR(SDL_GetError());
+		return false;
+	}
+
+	SDL_Surface *formattedSurface = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA32);
+	SDL_DestroySurface(surface);
+
+	if (!formattedSurface)
+	{
+		GCC_ERROR(SDL_GetError());
+		return false;
+	}
+
+	glGenTextures(1, &(extra->m_texture_id));
+	glBindTexture(GL_TEXTURE_2D, extra->m_texture_id);
+	glTexImage2D(
+		GL_TEXTURE_2D,
+		0,
+		GL_RGBA,
+		formattedSurface->w,
+		formattedSurface->h,
+		0,
+		GL_RGBA,
+		GL_UNSIGNED_BYTE,
+		formattedSurface->pixels
+	);
+
+	SDL_DestroySurface(formattedSurface);
+
+	// set texture parameters
+	glGenerateMipmap(GL_TEXTURE_2D);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+	// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+	GLfloat maxAnisotropy = 0.0f;
+	glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &maxAnisotropy); 
+	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, maxAnisotropy);
+
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+	
+	glBindTexture(GL_TEXTURE_2D, 0);
+
+	handle->SetExtra(extra);
+
+	return true;
+}

+ 103 - 0
Source/GCC4/Graphics3D/Material.h

@@ -0,0 +1,103 @@
+#pragma once
+//========================================================================
+// File: Material.h - stores texture and material information for D3D9 and D3D11
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+//========================================================================
+//  Content References in Game Coding Complete 4th Edition
+// 
+//  class Material				- Chapter 14, page 485
+
+#include "Geometry.h"
+#include "../ResourceCache/ResCache.h"
+#include <GL/glew.h>
+
+class Material
+{
+private:
+	Color m_Ambient;
+	Color m_Diffuse;
+	Color m_Specular;
+	Color m_Emissive;
+
+	float m_Power;
+
+public:
+	Material();
+	void SetAmbient(const Color &color);
+	const Color GetAmbient() { return m_Ambient; }
+
+	void SetDiffuse(const Color &color);
+	const Color GetDiffuse() { return m_Diffuse; }
+
+	void SetSpecular(const Color &color, const float power);
+	void GetSpecular(Color &_color, float &_power)
+		{ _color = m_Specular; _power = m_Power; }
+
+	void SetEmissive(const Color &color);
+	const Color GetEmissive() { return m_Emissive; }
+
+	void SetAlpha(const float alpha);
+	bool HasAlpha() const { return GetAlpha() != fOPAQUE; }
+	float GetAlpha() const { return m_Diffuse.a; }
+
+	void D3Use9();
+};
+
+class OpenGLTextureResourceExtraData : public IResourceExtraData
+{
+	friend class TextureResourceLoader;
+public:
+	OpenGLTextureResourceExtraData();
+	virtual ~OpenGLTextureResourceExtraData();
+	virtual std::string VToString() { return "OpenGLTextureResourceExtraData"; }
+	GLuint GetTextureId() { return m_texture_id; }
+	
+protected:
+	GLuint m_texture_id;
+};
+
+// 
+//  class TextureResourceLoader				- Chapter 14, page 492
+//
+class TextureResourceLoader : public IResourceLoader
+{
+	virtual bool VUseRawFile() { return false; }
+	virtual bool VDiscardRawBufferAfterLoad() { return true; }
+	virtual unsigned int VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize);
+	virtual bool VLoadResource(char *rawBuffer, unsigned int rawSize, std::shared_ptr<ResHandle> handle);
+};

+ 182 - 0
Source/GCC4/Graphics3D/Mesh.cpp

@@ -0,0 +1,182 @@
+#include "../Unix/GameCodeStd.h"
+
+#include "../GameCode4/GameCode.h"
+#include "../ResourceCache/ResCache.h"
+#include "OpenGLRenderer.h"
+#include "Lights.h"
+#include "Mesh.h"
+// #include "Raycast.h"
+#include "SceneNodes.h"
+
+
+std::shared_ptr<IResourceLoader> CreateGlbMeshResourceLoader()
+{
+	return std::shared_ptr<IResourceLoader>(GCC_NEW GlbMeshResourceLoader());
+}
+
+unsigned int GlbMeshResourceLoader::VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize)
+{
+	// The raw data of the SDK Mesh file is needed by the CDXUTMesh class, so we're going to keep it around.
+	return rawSize;
+}
+
+//
+// SdkMeshResourceLoader::VLoadResource						- Chapter 16, page 561
+//
+bool GlbMeshResourceLoader::VLoadResource(char *rawBuffer, unsigned int rawSize, std::shared_ptr<ResHandle> handle)
+{
+	std::shared_ptr<OpenGLGlbMeshResourceExtraData> extra = std::shared_ptr<OpenGLGlbMeshResourceExtraData>(GCC_NEW OpenGLGlbMeshResourceExtraData());
+
+	// load the mesh
+	extra->m_pScene = aiImportFileFromMemory(rawBuffer, rawSize, 0, "glb");
+
+	if (!extra->m_pScene || extra->m_pScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !extra->m_pScene->mRootNode) {
+	    GCC_ERROR(std::string("Failed to open scene file: ") + aiGetErrorString());
+	    return false;
+	}
+
+	handle->SetExtra(std::shared_ptr<OpenGLGlbMeshResourceExtraData>(extra));
+
+	return true;
+}
+
+OpenGLShaderMeshNode::OpenGLShaderMeshNode(const ActorId actorId,
+	WeakBaseRenderComponentPtr renderComponent,
+	std::string meshFileName,
+	RenderPass renderPass,
+	const glm::mat4 t)
+: SceneNode(actorId, renderComponent, renderPass, t),
+  m_vao(0),
+  m_vbo(0),
+  m_ebo(0),
+  m_numIndices(0),
+  m_numMeshes(0)
+{
+	m_meshFileName = meshFileName;
+}
+
+int OpenGLShaderMeshNode::VOnRestore(Scene *pScene)
+{
+	m_ShaderProgram.OnRestore(pScene);
+
+	// Force the Mesh to reload
+	Resource resource(m_meshFileName);
+	std::shared_ptr<ResHandle> pResourceHandle = g_pApp->m_ResCache->GetHandle(&resource);
+	std::shared_ptr<OpenGLGlbMeshResourceExtraData> extra = static_pointer_cast<OpenGLGlbMeshResourceExtraData>(pResourceHandle->GetExtra());
+
+	for (int i = 0; i < m_numMeshes; i++) {
+		glDeleteVertexArrays(1, &m_vao[i]);
+		glDeleteBuffers(1, &m_vbo[i]);
+		glDeleteBuffers(1, &m_ebo[i]);
+	}
+
+	if (m_vao) { delete[] m_vao; }
+	if (m_vbo) { delete[] m_vbo; }
+	if (m_ebo) { delete[] m_ebo; }
+	if (m_numIndices) { delete[] m_numIndices; }
+	if (m_numVerts) { delete[] m_numVerts; }
+
+	m_numMeshes = extra->m_pScene->mNumMeshes;
+	m_vao = GCC_NEW GLuint[m_numMeshes];
+	m_vbo = GCC_NEW GLuint[m_numMeshes];
+	m_ebo = GCC_NEW GLuint[m_numMeshes];
+	m_numIndices = GCC_NEW size_t[m_numMeshes];
+	m_numVerts = GCC_NEW size_t[m_numMeshes];
+
+	for (int i = 0; i < extra->m_pScene->mNumMeshes; i++)
+	{
+		const aiMesh* p_AIMesh = extra->m_pScene->mMeshes[i];
+
+		m_numVerts[i] = p_AIMesh->mNumVertices;
+		VertexUnlitTextured *pVerts = GCC_NEW VertexUnlitTextured[m_numVerts[i]];
+
+		GCC_ASSERT(pVerts && "Out of memory in OpenGLShaderMeshNode::VOnRestore");
+		if (!pVerts)
+			return 1;
+
+		for (int j = 0; j < m_numVerts[i]; j++)
+		{
+			pVerts[j].Pos = glm::vec3(
+				p_AIMesh->mVertices[j].x,
+				p_AIMesh->mVertices[j].y,
+				p_AIMesh->mVertices[j].z
+			);
+			pVerts[j].Normal = glm::vec3(
+				p_AIMesh->mNormals[j].x,
+				p_AIMesh->mNormals[j].y,
+				p_AIMesh->mNormals[j].z
+			);
+			pVerts[j].Uv = glm::vec2(
+				p_AIMesh->mTextureCoords[0][j].x,
+				p_AIMesh->mTextureCoords[0][j].y
+			);
+		}
+
+		m_numIndices[i] = p_AIMesh->mNumFaces * 3;
+		GLuint *pIndices = GCC_NEW GLuint[m_numIndices[i]];
+
+		GCC_ASSERT(pIndices && "Out of memory in OpenGLShaderMeshNode::VOnRestore");
+		if (!pIndices)
+		{
+			delete[] pVerts;
+			return 1;
+		}
+
+		GLuint *current = pIndices;
+		for (int j = 0; j < p_AIMesh->mNumFaces; j++)
+		{
+			*(current + 0) = p_AIMesh->mFaces[j].mIndices[0];
+			*(current + 1) = p_AIMesh->mFaces[j].mIndices[1];
+			*(current + 2) = p_AIMesh->mFaces[j].mIndices[2];
+			current += 3;
+		}
+
+		glCreateVertexArrays(1, &m_vao[i]);
+
+		glCreateBuffers(1, &m_vbo[i]);
+		glNamedBufferStorage(m_vbo[i], sizeof(VertexUnlitTextured) * m_numVerts[i], pVerts, 0);
+
+		glVertexArrayVertexBuffer(m_vao[i], 0, m_vbo[i], 0, sizeof(VertexUnlitTextured));
+
+		glEnableVertexArrayAttrib(m_vao[i], 0);
+		glVertexArrayAttribFormat(m_vao[i], 0, 3, GL_FLOAT, GL_FALSE, 0);
+		glVertexArrayAttribBinding(m_vao[i], 0, 0);
+
+		glEnableVertexArrayAttrib(m_vao[i], 1);
+		glVertexArrayAttribFormat(m_vao[i], 1, 3, GL_FLOAT, GL_FALSE, offsetof(VertexUnlitTextured, Normal));
+		glVertexArrayAttribBinding(m_vao[i], 1, 0);
+
+		glEnableVertexArrayAttrib(m_vao[i], 2);
+		glVertexArrayAttribFormat(m_vao[i], 2, 2, GL_FLOAT, GL_FALSE,  offsetof(VertexUnlitTextured, Uv));
+		glVertexArrayAttribBinding(m_vao[i], 2, 0);
+
+		delete[] pVerts;
+
+		glCreateBuffers(1, &m_ebo[i]);
+		glNamedBufferStorage(m_ebo[i], sizeof(GLuint) * m_numIndices[i], pIndices, 0);
+		glVertexArrayElementBuffer(m_vao[i], m_ebo[i]);
+
+		delete[] pIndices;
+	}
+
+
+	// TODO (munnellg) - calcualte the bounding sphere here
+	
+	return 1;
+}
+
+int OpenGLShaderMeshNode::VRender(Scene *pScene)
+{
+	// GridRenderComponent* grc = static_cast<GridRenderComponent*>(m_RenderComponent);
+	// m_ShaderProgram.SetTexture(grc->GetTextureResource());
+	m_ShaderProgram.SetupRender(pScene, this);
+
+	for (int i = 0; i < m_numMeshes; i++)
+	{
+		glBindVertexArray(m_vao[i]);
+		glDrawElements(GL_TRIANGLES, m_numIndices[i], GL_UNSIGNED_INT, 0);
+	}
+
+	glBindVertexArray(0);
+	return 0;
+}

+ 116 - 0
Source/GCC4/Graphics3D/Mesh.h

@@ -0,0 +1,116 @@
+#pragma once
+//========================================================================
+// File: Mesh.h - classes to render meshes in D3D9 and D3D11
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "Geometry.h"
+#include "SceneNodes.h"
+#include "Material.h"
+#include "Shaders.h"
+#include "../ResourceCache/ResCache.h"
+
+#include <assimp/cimport.h>
+#include <assimp/scene.h>
+#include <assimp/postprocess.h>
+
+//
+// class D3DSdkMeshResourceExtraData11					- Chapter 16, page 561
+//
+class OpenGLGlbMeshResourceExtraData : public IResourceExtraData
+{
+	friend class GlbMeshResourceLoader;
+
+public:
+	OpenGLGlbMeshResourceExtraData() { }
+	virtual ~OpenGLGlbMeshResourceExtraData() { if (m_pScene) aiReleaseImport(m_pScene); }
+	virtual std::string VToString() { return "OpenGLGlbMeshResourceExtraData"; }
+
+	const aiScene* m_pScene;
+};
+
+//
+// class SdkMeshResourceLoader							- Chapter 16, page 561
+//
+class GlbMeshResourceLoader : public IResourceLoader
+{
+public:
+	virtual bool VUseRawFile() { return false; }
+	virtual bool VDiscardRawBufferAfterLoad() { return false; }
+	virtual unsigned int VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize);
+	virtual bool VLoadResource(char *rawBuffer, unsigned int rawSize, std::shared_ptr<ResHandle> handle);
+	virtual std::string VGetPattern() { return "*.glb"; }
+};
+
+////////////////////////////////////////////////////
+//
+// class TeapotMeshNode9				- Chapter X, page Y
+//
+////////////////////////////////////////////////////
+
+class OpenGLShaderMeshNode : public SceneNode
+{
+public:
+	OpenGLShaderMeshNode(const ActorId actorId,
+		WeakBaseRenderComponentPtr renderComponent,
+		std::string meshFileName,
+		RenderPass renderPass,
+		const glm::mat4 t);
+
+	virtual int VOnRestore(Scene *pScene);
+	virtual int VOnLostDevice(Scene *pScene) { return 0; }
+	virtual int VRender(Scene *pScene);
+	// virtual int VPick(Scene *pScene, RayCast *pRayCast);
+	
+protected:
+	std::string				m_meshFileName;
+
+	GLuint					*m_vao;
+	GLuint					*m_vbo;
+	GLuint					*m_ebo;
+	size_t					*m_numIndices;
+	size_t					*m_numVerts;
+	size_t					m_numMeshes;
+	OpenGLShaderProgram		m_ShaderProgram;
+};
+
+class OpenGLTeapotMeshNode : public OpenGLShaderMeshNode
+{
+public:
+	OpenGLTeapotMeshNode(const ActorId actorId, WeakBaseRenderComponentPtr renderComponent, RenderPass renderPass, glm::mat4 t)
+		: OpenGLShaderMeshNode(actorId, renderComponent, "art/3d assets/fantasy town kit/models/gltf format/hedge.glb", renderPass, t) { }
+	bool VIsVisible() { return true; }
+};

+ 255 - 0
Source/GCC4/Graphics3D/MovementController.cpp

@@ -0,0 +1,255 @@
+//========================================================================
+// File: MovementController.cpp
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+
+#include "Geometry.h"
+#include "MovementController.h"
+#include "SceneNodes.h"
+
+
+////////////////////////////////////////////////////
+// MovementController Implementation			- Chapter 10, page 282
+////////////////////////////////////////////////////
+
+#define MAX(a, b) ((a) >= (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+MovementController::MovementController(std::shared_ptr<SceneNode> object, float initialYaw, float initialPitch, bool rotateWhenLButtonDown)
+: m_object(object)
+{
+	m_object->VGet()->Transform(&m_matToWorld, &m_matFromWorld);
+
+	m_fTargetYaw = m_fYaw = glm::degrees(-initialYaw);
+	m_fTargetPitch = m_fPitch = glm::degrees(initialPitch);
+
+	m_maxSpeed = 30.0f;			// 30 meters per second
+	m_currentSpeed = 0.0f;
+
+	glm::vec3 pos = geometry::GetPosition(m_matToWorld);
+
+	m_matPosition = geometry::BuildTranslation(pos);
+
+	float mouseX, mouseY;
+	SDL_MouseButtonFlags mouseState = SDL_GetMouseState(&mouseX, &mouseY);
+	m_lastMousePos.x = (int) mouseX;
+	m_lastMousePos.y = (int) mouseY;
+
+	memset(m_bKey, 0x00, sizeof(m_bKey));
+
+	m_mouseLButtonDown = mouseState & SDL_BUTTON_LEFT;
+	m_bRotateWhenLButtonDown = rotateWhenLButtonDown;
+}
+
+bool MovementController::VOnPointerButtonDown(const Point &mousePos, const int radius, const std::string &buttonName)
+{
+	if (buttonName == "PointerLeft")
+	{
+		m_mouseLButtonDown = true;
+
+		// We want mouse movement to be relative to the position
+		// the cursor was at when the user first presses down on
+		// the left button
+		m_lastMousePos = mousePos;
+		return true;
+	}
+	return false;
+}
+
+bool MovementController::VOnPointerButtonUp(const Point &mousePos, const int radius, const std::string &buttonName)
+{
+	if (buttonName == "PointerLeft")
+	{
+		m_mouseLButtonDown = false;
+		return true;
+	}
+	return false;
+}
+
+
+//  class MovementController::VOnMouseMove		- Chapter 10, page 282
+
+bool MovementController::VOnPointerMove(const Point &mousePos, const int radius)
+{	
+	// There are two modes supported by this controller.
+	if (m_bRotateWhenLButtonDown)
+	{
+		// Mode 1 - rotate the view only when the left mouse button is down
+		// Only look around if the left button is down
+		if(m_lastMousePos!=mousePos && m_mouseLButtonDown)
+		{
+			m_fTargetYaw = m_fTargetYaw + (mousePos.x - m_lastMousePos.x);
+		m_fTargetPitch = m_fTargetPitch + (mousePos.y - m_lastMousePos.y);
+			m_lastMousePos = mousePos;
+		}
+	}
+	else if(m_lastMousePos!=mousePos)
+	{
+		m_fTargetYaw = m_fTargetYaw + (mousePos.x - m_lastMousePos.x);
+		m_fTargetPitch = m_fTargetPitch + (m_lastMousePos.y - mousePos.y);
+		m_lastMousePos = mousePos;
+	}
+
+	return true;
+}
+
+//  class MovementController::OnUpdate			- Chapter 10, page 283
+
+void MovementController::OnUpdate(uint64_t const deltaMilliseconds)
+{
+	//if (m_bKey['Q'])
+	//{
+	//	// This code is a cheat to position the camera exactly in a given
+	//	// spot so I can take screen shots!
+
+	//	Mat4x4 camTranslate;
+	//	D3DXMatrixTranslation(&m_matPosition, 8.847f, 7.055f, 11.618f);
+
+	//	m_fTargetYaw = m_fYaw += -64.35f;
+	//	m_fTargetPitch = m_fPitch = 28.57f;
+
+	//	// Calculate the new rotation matrix from the camera
+	//	// yaw and pitch.
+	//	Mat4x4 matRot;
+	//	D3DXMatrixRotationYawPitchRoll(&matRot, DEGREES_TO_RADIANS(m_fYaw), DEGREES_TO_RADIANS(m_fPitch), 0);
+
+	//	// Create the new object-to-world matrix, and the
+	//	// new world-to-object matrix. 
+	//	D3DXMatrixMultiply(&m_matToWorld, &matRot, &m_matPosition);
+	//	D3DXMatrixInverse(&m_matFromWorld, NULL, &m_matToWorld);
+
+	//	m_object->VSetTransform(&m_matToWorld, &m_matFromWorld);
+	//	return;
+	//}
+
+	bool bTranslating = false;
+	glm::vec4 atWorld(0,0,0,0);
+	glm::vec4 rightWorld(0,0,0,0);
+	glm::vec4 upWorld(0,0,0,0);
+
+	if (m_bKey[SDL_SCANCODE_W] || m_bKey[SDL_SCANCODE_S])
+	{
+		// In D3D, the "look at" default is always
+		// the positive Z axis.
+		glm::vec4 at  = -g_Forward4;
+		if (m_bKey[SDL_SCANCODE_S])
+			at *= -1;
+
+		// This will give us the "look at" vector 
+		// in world space - we'll use that to move
+		// the camera.
+		atWorld = m_matToWorld * at;
+		bTranslating = true;
+	}
+
+	if (m_bKey[SDL_SCANCODE_A] || m_bKey[SDL_SCANCODE_D])
+	{
+		// In D3D, the "right" default is always
+		// the positive X axis.
+		glm::vec4 right = g_Right4;
+		if (m_bKey[SDL_SCANCODE_A])
+			right *= -1;
+
+		// This will give us the "right" vector 
+		// in world space - we'll use that to move
+		// the camera
+		rightWorld = m_matToWorld * right;
+		bTranslating = true;
+	}
+
+	if (m_bKey[SDL_SCANCODE_SPACE] || m_bKey[SDL_SCANCODE_C] || m_bKey[SDL_SCANCODE_X])
+	{
+		// In D3D, the "up" default is always
+		// the positive Y axis.
+		glm::vec4 up = g_Up4;
+		if (!m_bKey[SDL_SCANCODE_SPACE])
+			up *= -1;
+
+		//Unlike strafing, Up is always up no matter
+		//which way you are looking
+		upWorld = up;
+		bTranslating = true;
+	}
+
+	// Handling rotation as a result of mouse position
+	{
+		// The secret formula!!! Don't give it away!
+		//If you are seeing this now, then you must be some kind of elite hacker!
+		m_fYaw += (m_fTargetYaw - m_fYaw) * ( .35f );
+		m_fTargetPitch = MAX(-90, MIN(90, m_fTargetPitch));
+		m_fPitch += (m_fTargetPitch - m_fPitch) * ( .35f );
+
+		// Calculate the new rotation matrix from the camera
+		// yaw and pitch.
+		glm::mat4 matRot = geometry::BuildYawPitchRoll(glm::radians(-m_fYaw), glm::radians(m_fPitch), 0);
+
+		// Create the new object-to-world matrix, and the
+		// new world-to-object matrix.
+
+		m_matToWorld = m_matPosition * matRot;
+		m_matFromWorld = glm::inverse(m_matToWorld);
+		m_object->VSetTransform(m_matToWorld, m_matFromWorld);
+	}
+
+	if (bTranslating)
+	{
+		float elapsedTime = (float)deltaMilliseconds / 1000.0f;
+
+		glm::vec3 direction = atWorld + rightWorld + upWorld;
+		direction = glm::normalize(direction);
+
+		// Ramp the acceleration by the elapsed time
+		float numberOfSeconds = 5.f;
+		m_currentSpeed += m_maxSpeed * ( (elapsedTime*elapsedTime) / numberOfSeconds);
+		if (m_currentSpeed > m_maxSpeed)
+			m_currentSpeed = m_maxSpeed;
+
+		direction *= m_currentSpeed;
+
+		glm::vec3 pos = geometry::GetPosition(m_matPosition) + direction;
+		geometry::SetPosition(m_matPosition, pos);
+		geometry::SetPosition(m_matToWorld, pos);
+
+		m_matFromWorld = glm::inverse(m_matToWorld);
+		m_object->VSetTransform(m_matToWorld, m_matFromWorld);
+	}
+	else
+	{
+		m_currentSpeed = 0.0f;
+	}
+}

+ 99 - 0
Source/GCC4/Graphics3D/MovementController.h

@@ -0,0 +1,99 @@
+#pragma once
+//========================================================================
+// File: MovementController.h
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../GameCode4/interfaces.h"
+#include "Geometry.h"
+
+
+// Forward declarations
+class SceneNode;
+
+////////////////////////////////////////////////////
+//
+// MovementController Description
+//
+//    Implements a WASD style movement controller
+//
+//  class MovementController		- Chapter 10, page 281
+//
+////////////////////////////////////////////////////
+
+class MovementController : public IPointerHandler, public IKeyboardHandler
+{
+protected:
+	glm::mat4 m_matFromWorld;
+	glm::mat4 m_matToWorld;
+	glm::mat4 m_matPosition;
+
+	Point 					m_lastMousePos;
+	bool					m_bKey[256];			// Which keys are up and down
+
+	// Orientation Controls
+	float		m_fTargetYaw;
+	float		m_fTargetPitch;
+	float		m_fYaw;
+	float		m_fPitch;
+	float		m_fPitchOnDown;
+	float		m_fYawOnDown;
+	float		m_maxSpeed;
+	float		m_currentSpeed;
+
+	// Added for Ch19/20 refactor
+	bool 		m_mouseLButtonDown;
+	bool 		m_bRotateWhenLButtonDown;
+
+	std::shared_ptr<SceneNode> m_object;
+
+public:
+	MovementController(std::shared_ptr<SceneNode> object, float initialYaw, float initialPitch, bool rotateWhenLButtonDown);
+	void SetObject(std::shared_ptr<SceneNode> newObject);
+
+	void OnUpdate(uint64_t const elapsedMs);
+
+public:
+	virtual bool VOnPointerMove(const Point &pos, const int radius);
+	virtual bool VOnPointerButtonDown(const Point &pos, const int radius, const std::string &buttonName);
+	virtual bool VOnPointerButtonUp(const Point &pos, const int radius, const std::string &buttonName);
+
+	virtual bool VOnKeyDown(const unsigned char c) { m_bKey[c] = true; return true; }
+	virtual bool VOnKeyUp(const unsigned char c)  { m_bKey[c] = false; return true; }
+
+	const glm::mat4 GetToWorld() { return m_matToWorld; }
+	const glm::mat4 GetFromWorld() { return m_matFromWorld; }
+};

+ 76 - 0
Source/GCC4/Graphics3D/OpenGLRenderer.cpp

@@ -0,0 +1,76 @@
+#include "OpenGLRenderer.h"
+#include "../Unix/GameCodeStd.h"
+#include <SDL3/SDL.h>
+#include <GL/glew.h>
+#include <imgui.h>
+#include <imgui_impl_sdl3.h>
+#include <imgui_impl_opengl3.h>
+
+void OpenGLRenderer46::VSetBackgroundColor(unsigned char bgA, unsigned char bgR, unsigned char bgG, unsigned char bgB)
+{
+	glClearColor(
+		(float) bgR / 255.0f,
+		(float) bgG / 255.0f,
+		(float) bgB / 255.0f,
+		(float) bgA / 255.0f
+	);
+}
+
+int OpenGLRenderer46::VOnRestore()
+{
+	return 0;
+}
+
+void OpenGLRenderer46::VShutdown()
+{
+
+}
+
+bool OpenGLRenderer46::VPreRender()
+{
+	// clear screen
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    // Start the Dear ImGui frame
+	ImGui_ImplOpenGL3_NewFrame();
+	ImGui_ImplSDL3_NewFrame();
+	ImGui::NewFrame();
+    return true;
+}
+
+bool OpenGLRenderer46::VPostRender()
+{
+
+	// Rendering
+	ImGui::Render();
+	
+	// update the screen
+	ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
+	SDL_GL_SwapWindow(g_pApp->m_Window);
+	return true;
+}
+
+std::shared_ptr<IRenderState> OpenGLRenderer46::VPrepareAlphaPass()
+{
+	return std::shared_ptr<IRenderState>();
+}
+
+std::shared_ptr<IRenderState> OpenGLRenderer46::VPrepareSkyBoxPass()
+{
+	return std::shared_ptr<IRenderState>();
+}
+
+void OpenGLRenderer46::VSetWorldTransform(glm::mat4 m)
+{
+	// TODO(munnellg) - implement
+}
+
+void OpenGLRenderer46::VSetViewTransform(glm::mat4 m)
+{
+	// TODO(munnellg) - implement
+}
+
+void OpenGLRenderer46::VSetProjectionTransform(glm::mat4 m)
+{
+	// TODO(munnellg) - implement
+}

+ 59 - 0
Source/GCC4/Graphics3D/OpenGLRenderer.h

@@ -0,0 +1,59 @@
+#pragma once
+
+#include "../GameCode4/interfaces.h"
+
+#include <memory>
+
+//
+// struct ConstantBuffer_Matrices				- Chapter X, page Y
+//
+struct alignas(16) ConstantBuffer_Matrices
+{
+	glm::mat4 m_WorldViewProj;
+	glm::mat4 m_World;
+};
+
+//
+// struct ConstantBuffer_Material				- Chapter X, page Y
+//
+struct alignas(16) ConstantBuffer_Material
+{
+	glm::vec4 m_vDiffuseObjectColor;
+	glm::vec4 m_vAmbientObjectColor;
+	bool m_bHasTexture;
+	glm::vec3 m_vUnused;
+};
+
+#define MAXIMUM_LIGHTS_SUPPORTED (8)
+
+//
+// struct ConstantBuffer_Lighting				- Chapter X, page Y
+//
+struct alignas(16) ConstantBuffer_Lighting
+{
+	glm::vec4 m_vLightDiffuse[MAXIMUM_LIGHTS_SUPPORTED];
+	glm::vec4 m_vLightDir[MAXIMUM_LIGHTS_SUPPORTED];
+	glm::vec4 m_vLightAmbient;
+	unsigned int m_nNumLights;
+	glm::vec3 m_vUnused;
+};
+
+class OpenGLRenderer46 : public IRenderer
+{
+public:
+	OpenGLRenderer46() { }
+
+	virtual int VOnRestore() override;
+	virtual void VSetBackgroundColor(unsigned char bgA, unsigned char bgR, unsigned char bgG, unsigned char bgB) override;
+	virtual void VShutdown() override;
+	virtual bool VPreRender() override;
+	virtual bool VPostRender() override;
+	virtual void VCalcLighting(Lights *lights, int maximumLights) { }
+	
+	virtual void VSetWorldTransform(glm::mat4 m);
+	virtual void VSetViewTransform(glm::mat4 m);
+	virtual void VSetProjectionTransform(glm::mat4 m);
+
+	virtual std::shared_ptr<IRenderState> VPrepareAlphaPass() override;
+	virtual std::shared_ptr<IRenderState> VPrepareSkyBoxPass() override;
+};

+ 230 - 0
Source/GCC4/Graphics3D/Scene.cpp

@@ -0,0 +1,230 @@
+//========================================================================
+// File: Scene.cpp - implements the container class for 3D Graphics scenes
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "Scene.h"
+#include "../Unix/GameCodeStd.h"
+
+#include "../GameCode4/GameCode.h"
+#include "../EventManager/EventManager.h"
+#include "../EventManager/Events.h"
+#include "../Utilities/String.h"
+
+#include "Geometry.h"
+#include "Lights.h"
+
+
+////////////////////////////////////////////////////
+// Scene Implementation
+////////////////////////////////////////////////////
+
+
+//
+// Scene::Scene						- Chapter 16, page 539
+//
+//    Note: The shared_ptr<IRenderer> was added to allow for both D3D9 and D3D11 renderer implementations.
+//          The book only describes D3D11, so to find all the differences, just search for m_Renderer!
+//
+Scene::Scene(std::shared_ptr<IRenderer> renderer)
+{
+	m_Root.reset(GCC_NEW RootNode());
+	m_Renderer = renderer;
+	m_LightManager = GCC_NEW LightManager;
+
+	// D3DXCreateMatrixStack(0, &m_MatrixStack);
+	m_MatrixStack.push(glm::mat4(1.0f));
+	
+	// [mrmike] - event delegates were added post-press
+	IEventManager* pEventMgr = IEventManager::Get();
+	pEventMgr->VAddListener(MakeDelegate(this, &Scene::NewRenderComponentDelegate), EvtData_New_Render_Component::sk_EventType);
+	// pEventMgr->VAddListener(MakeDelegate(this, &Scene::DestroyActorDelegate), EvtData_Destroy_Actor::sk_EventType);
+	// pEventMgr->VAddListener(MakeDelegate(this, &Scene::MoveActorDelegate), EvtData_Move_Actor::sk_EventType);
+	pEventMgr->VAddListener(MakeDelegate(this, &Scene::ModifiedRenderComponentDelegate), EvtData_Modified_Render_Component::sk_EventType);
+}
+
+//
+// Scene::~Scene					- Chapter 16, page 539
+//
+Scene::~Scene()
+{
+	// [mrmike] - event delegates were added post-press!
+	IEventManager* pEventMgr = IEventManager::Get();
+	pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::NewRenderComponentDelegate), EvtData_New_Render_Component::sk_EventType);
+	// pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::DestroyActorDelegate), EvtData_Destroy_Actor::sk_EventType);
+	// pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::MoveActorDelegate), EvtData_Move_Actor::sk_EventType);
+
+	pEventMgr->VRemoveListener(MakeDelegate(this, &Scene::ModifiedRenderComponentDelegate), EvtData_Modified_Render_Component::sk_EventType);
+
+	// SAFE_RELEASE(m_MatrixStack);
+	SAFE_DELETE(m_LightManager);
+}
+
+//
+// Scene::OnRender					- Chapter 16, page 539
+//
+int Scene::OnRender()
+{
+	// The render passes usually go like this 
+	// 1. Static objects & terrain
+	// 2. Actors (dynamic objects that can move)
+	// 3. The Sky
+	// 4. Anything with Alpha
+
+	if (m_Root && m_Camera)
+	{
+		// The scene root could be anything, but it
+		// is usually a SceneNode with the identity
+		// matrix
+
+		m_Camera->SetViewTransform(this);
+
+		m_LightManager->CalcLighting(this);
+
+		if (m_Root->VPreRender(this)==0)
+		{
+			m_Root->VRender(this);
+			m_Root->VRenderChildren(this);
+			m_Root->VPostRender(this);
+		}
+		// RenderAlphaPass();
+	}
+
+	return 0;
+}
+
+
+
+//
+// Scene::OnUpdate					- Chapter 16, page 540
+//
+int Scene::OnUpdate(const int deltaMilliseconds)
+{
+	if (!m_Root)
+		return 0;
+
+	static Uint64 lastTime = SDL_GetTicks();
+	Uint64 elapsedTime = 0;
+	Uint64 now = SDL_GetTicks();
+
+	elapsedTime = now - lastTime;
+	lastTime = now;
+
+	return m_Root->VOnUpdate(this, elapsedTime);
+}
+
+//
+// Scene::OnRestore					- Chapter 16, page 540
+//
+int Scene::OnRestore()
+{
+	if (!m_Root)
+		return 0;
+
+	if (m_Renderer->VOnRestore() != 0)
+		return 1;
+
+	return m_Root->VOnRestore(this);
+}
+
+bool Scene::AddChild(ActorId id, std::shared_ptr<ISceneNode> kid)
+{ 
+	if (id != INVALID_ACTOR_ID)
+	{
+		// This allows us to search for this later based on actor id
+		m_ActorMap[id] = kid;	
+	}
+
+	std::shared_ptr<LightNode> pLight = dynamic_pointer_cast<LightNode>(kid);
+	if (pLight != NULL && m_LightManager->m_Lights.size()+1 < MAXIMUM_LIGHTS_SUPPORTED)
+	{
+		m_LightManager->m_Lights.push_back(pLight);
+	}
+	return m_Root->VAddChild(kid);
+}
+
+bool Scene::RemoveChild(ActorId id)
+{
+	if (id == INVALID_ACTOR_ID)
+		return false;
+	std::shared_ptr<ISceneNode> kid = FindActor(id);
+	std::shared_ptr<LightNode> pLight = dynamic_pointer_cast<LightNode>(kid);
+	if (pLight != NULL)
+	{
+		m_LightManager->m_Lights.remove(pLight);
+	}
+	m_ActorMap.erase(id);
+	return m_Root->VRemoveChild(id); 
+}
+
+
+
+void Scene::NewRenderComponentDelegate(IEventDataPtr pEventData)
+{
+	std::shared_ptr<EvtData_New_Render_Component> pCastEventData = static_pointer_cast<EvtData_New_Render_Component>(pEventData);
+
+	ActorId actorId = pCastEventData->GetActorId();
+	std::shared_ptr<SceneNode> pSceneNode(pCastEventData->GetSceneNode());
+
+	// FUTURE WORK: Add better error handling here.		
+    if (pSceneNode->VOnRestore(this) != 0)
+    {
+		std::string error = "Failed to restore scene node to the scene for actorid " + ToStr(actorId);
+        GCC_ERROR(error);
+        return;
+    }
+
+	AddChild(actorId, pSceneNode);
+}
+
+void Scene::ModifiedRenderComponentDelegate(IEventDataPtr pEventData)
+{
+	// TODO(munnellg) - implement
+}
+
+//
+// Scene::FindActor					- Chapter 16, page 542
+//
+std::shared_ptr<ISceneNode> Scene::FindActor(ActorId id)
+{
+	SceneActorMap::iterator i = m_ActorMap.find(id);
+	if (i==m_ActorMap.end())
+	{
+		return std::shared_ptr<ISceneNode>();
+	}
+
+	return i->second;
+}

+ 140 - 0
Source/GCC4/Graphics3D/Scene.h

@@ -0,0 +1,140 @@
+#pragma once
+//========================================================================
+// File: Scene.h - implements the container class for 3D Graphics scenes
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+
+#include "Geometry.h"
+#include "SceneNodes.h"
+#include "../EventManager/Events.h"
+
+#include <map>
+#include <stack>
+
+// Forward declarations
+////////////////////////////////////////////////////
+//
+// SceneActorMap Description				- Chapter 16, page Y
+//
+//   An STL map that allows fast lookup of a scene node given an ActorId.
+//
+////////////////////////////////////////////////////
+
+typedef std::map<ActorId, std::shared_ptr<ISceneNode> > SceneActorMap;
+
+
+////////////////////////////////////////////////////
+//
+// Scene Description						- Chapter 16, page 536
+//
+// A heirarchical container of scene nodes, which
+// are classes that implemente the ISceneNode interface
+//
+////////////////////////////////////////////////////
+
+class CameraNode;
+class SkyNode;
+class LightNode;
+class LightManager;
+
+class Scene
+{
+protected:
+	std::shared_ptr<SceneNode>  m_Root;
+	std::shared_ptr<CameraNode> m_Camera;
+	std::shared_ptr<IRenderer>  m_Renderer;
+
+	std::stack<glm::mat4>	m_MatrixStack;
+	SceneActorMap 			m_ActorMap;
+
+	LightManager			*m_LightManager;
+
+public:
+	Scene(std::shared_ptr<IRenderer> renderer);
+	virtual ~Scene();
+
+	int OnRender();
+	int OnRestore();
+	int OnLostDevice();
+	int OnUpdate(const int deltaMilliseconds);
+	std::shared_ptr<ISceneNode> FindActor(ActorId id);
+	bool AddChild(ActorId id, std::shared_ptr<ISceneNode> kid);
+	bool RemoveChild(ActorId id);
+	
+	// event delegates
+    void NewRenderComponentDelegate(IEventDataPtr pEventData);
+    void ModifiedRenderComponentDelegate(IEventDataPtr pEventData);			// added post-press!
+    // void DestroyActorDelegate(IEventDataPtr pEventData);
+    // void MoveActorDelegate(IEventDataPtr pEventData);
+	
+	void SetCamera(std::shared_ptr<CameraNode> camera) { m_Camera = camera; }
+	const std::shared_ptr<CameraNode> GetCamera() const { return m_Camera; }
+
+	void PushAndSetMatrix(const glm::mat4 &toWorld)
+	{
+		// Note this code carefully!!!!! It is COMPLETELY different
+		// from some DirectX 9 documentation out there....
+		// Scene::PushAndSetMatrix - Chapter 16, page 541
+
+		m_MatrixStack.push(toWorld * m_MatrixStack.top());
+
+		// [munnellg] This isn't necessary for OpenGL, but we'll preserve it from teh book
+		// anyway as GCC4 does something similar with this call for DirectX 11 being a noop
+		glm::mat4 mat = m_MatrixStack.top();
+		m_Renderer->VSetWorldTransform(mat);
+	}
+
+	void PopMatrix()
+	{
+		m_MatrixStack.pop();
+
+		// [munnellg] This isn't necessary for OpenGL, but we'll preserve it from teh book
+		// anyway as GCC4 does something similar with this call for DirectX 11 being a noop
+		glm::mat4 mat = m_MatrixStack.top();
+		m_Renderer->VSetWorldTransform(mat);
+	}
+
+	const glm::mat4 GetTopMatrix()
+	{
+		// Scene::GetTopMatrix - Chapter 16, page 541
+		return m_MatrixStack.top();
+	}
+
+	LightManager *GetLightManager() { return m_LightManager; }
+
+	std::shared_ptr<IRenderer> GetRenderer() { return m_Renderer; }
+};

+ 646 - 0
Source/GCC4/Graphics3D/SceneNodes.cpp

@@ -0,0 +1,646 @@
+//========================================================================
+// SceneNodes.cpp - defines the base class for the 3D graphics scene graph, and
+//                  derived classes like RootNode, Alpha scene nodes, Camera, Grids, etc.                  
+//
+// Part of the GameCode4 Application
+//
+// GameCode4 is the sample application that encapsulates much of the source code
+// discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David
+// "Rez" Graham, published by Charles River Media. 
+// ISBN-10: 1133776574 | ISBN-13: 978-1133776574
+//
+// If this source code has found it's way to you, and you think it has helped you
+// in any way, do the authors a favor and buy a new copy of the book - there are 
+// detailed explanations in it that compliment this code well. Buy a copy at Amazon.com
+// by clicking here: 
+//    http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller=
+//
+// There's a companion web site at http://www.mcshaffry.com/GameCode/
+// 
+// The source code is managed and maintained through Google Code: 
+//    http://code.google.com/p/gamecode4/
+//
+// (c) Copyright 2012 Michael L. McShaffry and David Graham
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser GPL v3
+// as published by the Free Software Foundation.
+//
+// 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 
+// http://www.gnu.org/licenses/lgpl-3.0.txt for more details.
+//
+// You should have received a copy of the GNU Lesser GPL v3
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//
+//========================================================================
+
+#include "../Unix/GameCodeStd.h"
+
+#include "../Actors/RenderComponent.h"
+#include "../Actors/TransformComponent.h"
+
+#include "SceneNodes.h"
+#include "Scene.h"
+
+#include <glm/gtx/string_cast.hpp>
+
+////////////////////////////////////////////////////
+// SceneNodeProperties Implementation
+////////////////////////////////////////////////////
+
+SceneNodeProperties::SceneNodeProperties(void)
+{
+    m_ActorId = INVALID_ACTOR_ID;
+    m_Radius = 0;
+    m_RenderPass = RenderPass_0;
+    m_AlphaType = AlphaOpaque;
+}
+
+
+//
+// SceneNodeProperties::Transform			- Chapter 16, page 528
+//
+void SceneNodeProperties::Transform(glm::mat4 *toWorld, glm::mat4 *fromWorld) const
+{
+	if (toWorld)
+		*toWorld = m_ToWorld;
+	
+	if (fromWorld)
+		*fromWorld = m_FromWorld;
+}
+
+
+////////////////////////////////////////////////////
+// SceneNode Implementation
+////////////////////////////////////////////////////
+
+SceneNode::SceneNode(
+		ActorId actorId,
+		WeakBaseRenderComponentPtr renderComponent,
+		RenderPass renderPass,
+		const glm::mat4 to,
+		std::optional<const glm::mat4> from
+) { 
+	m_pParent= NULL;
+	m_Props.m_ActorId = actorId;
+	m_Props.m_Name = (renderComponent) ? renderComponent->VGetName() : "SceneNode";
+	m_Props.m_RenderPass = renderPass;
+	m_Props.m_AlphaType = AlphaOpaque;
+	m_RenderComponent = renderComponent;
+	VSetTransform(to, from); 
+	SetRadius(0);
+
+	// [mrmike] - these lines were moved to VOnRestore() post press
+	//Color color = (renderComponent) ? renderComponent->GetColor() : g_White;
+	//m_Props.m_Material.SetDiffuse(color);
+}
+
+
+SceneNode::~SceneNode()
+{
+}
+
+//
+// SceneNode::VOnRestore					- Chapter 16, page 532
+//
+int SceneNode::VOnRestore(Scene *pScene)
+{
+	Color color = (m_RenderComponent) ? m_RenderComponent->GetColor() : g_White;
+	m_Props.m_Material.SetDiffuse(color);
+
+	// This is meant to be called from any class
+	// that inherits from SceneNode and overloads
+	// VOnRestore()
+
+	SceneNodeList::iterator i = m_Children.begin();
+	SceneNodeList::iterator end = m_Children.end();
+	while (i != end)
+	{
+		(*i)->VOnRestore(pScene);
+		++i;
+	}
+	return 0;
+}
+
+//
+// SceneNode::VSetTransform					- Chapter 16, page 531
+//
+void SceneNode::VSetTransform(
+		const glm::mat4 toWorld,
+		std::optional<const glm::mat4> fromWorld
+) {
+	m_Props.m_ToWorld = toWorld;
+	if (!fromWorld)
+	{
+		m_Props.m_FromWorld = glm::inverse(m_Props.m_ToWorld);
+	}
+	else
+	{
+		m_Props.m_FromWorld = *fromWorld;
+	}
+}
+
+//
+// SceneNode::VPostRender					- Chapter 16, page 532
+//
+int SceneNode::VPreRender(Scene *pScene)
+{
+	StrongActorPtr pActor = MakeStrongPtr(g_pApp->GetGameLogic()->VGetActor(m_Props.m_ActorId));
+	if (pActor)
+	{
+		std::shared_ptr<TransformComponent> pTc = MakeStrongPtr(pActor->GetComponent<TransformComponent>(TransformComponent::g_Name));
+		if (pTc)
+		{
+			m_Props.m_ToWorld = pTc->GetTransform();
+		}
+	}
+
+	pScene->PushAndSetMatrix(m_Props.m_ToWorld);
+	return 0;
+}
+
+//
+// SceneNode::VIsVisible				- Chapter 16, page 533
+//
+bool SceneNode::VIsVisible(Scene *pScene) const
+{
+	// transform the location of this node into the camera space
+	// of the camera attached to the scene
+
+	// glm::mat4 toWorld, fromWorld;
+	// pScene->GetCamera()->VGet()->Transform(&toWorld, &fromWorld);
+
+	// glm::vec3 pos = GetWorldPosition();
+
+	// glm::vec3 fromWorldPos = fromWorld.Xform(pos);
+
+	// Frustum const &frustum = pScene->GetCamera()->GetFrustum();
+
+	// bool isVisible = frustum.Inside(fromWorldPos, VGet()->Radius());
+	// return isVisible;
+	return true;
+}
+
+//
+// SceneNode::VPostRender					- Chapter 16, page 532
+//
+int SceneNode::VPostRender(Scene *pScene)
+{
+	pScene->PopMatrix();
+	return 0;
+}
+
+//
+// SceneNode::VOnUpdate					- Chapter 16, page 532
+//
+int SceneNode::VOnUpdate(Scene *pScene, uint64_t const elapsedMs)
+{
+	// This is meant to be called from any class
+	// that inherits from SceneNode and overloads
+	// VOnUpdate()
+
+	SceneNodeList::iterator i = m_Children.begin();
+	SceneNodeList::iterator end = m_Children.end();
+
+	while (i != end)
+	{
+		(*i)->VOnUpdate(pScene, elapsedMs);
+		++i;
+	}
+	return 0;
+}
+
+//
+// SceneNode::VRenderChildren					- Chapter 16, page 533
+//
+int SceneNode::VRenderChildren(Scene *pScene)
+{
+	// Iterate through the children
+	SceneNodeList::iterator i = m_Children.begin();
+	SceneNodeList::iterator end = m_Children.end();
+
+	while (i != end)
+	{
+		if ((*i)->VPreRender(pScene) == 0)
+		{
+			// You could short-circuit rendering
+			// if an object returns E_FAIL from
+			// VPreRender()
+
+			// Don't render this node if you can't see it
+			if ((*i)->VIsVisible(pScene))
+			{
+				float alpha = (*i)->VGet()->m_Material.GetAlpha();
+				if (alpha==fOPAQUE)
+				{
+					(*i)->VRender(pScene);
+				}
+	// 			else if (alpha!=fTRANSPARENT)
+	// 			{
+	// 				// The object isn't totally transparent
+	// 				AlphaSceneNode *asn = GCC_NEW AlphaSceneNode;
+	// 			}
+				(*i)->VRenderChildren(pScene);
+			}
+
+			// [mrmike] post-press fix - if the parent is not visible, the childrend
+			//           shouldn't be visible either.
+			// (*i)->VRenderChildren(pScene);
+		}
+		(*i)->VPostRender(pScene);
+		++i;
+	}
+	return 0;
+}
+
+//
+// SceneNode::VAddChild					- Chapter 16, page 535
+//
+bool SceneNode::VAddChild(std::shared_ptr<ISceneNode> ikid)
+{
+	m_Children.push_back(ikid); 
+
+	std::shared_ptr<SceneNode> kid = static_pointer_cast<SceneNode>(ikid);
+
+	kid->m_pParent = this;					// [mrmike] Post-press fix - the parent was never set!
+
+	// The radius of the sphere should be fixed right here
+	glm::vec3 kidPos = geometry::GetPosition(kid->VGet()->ToWorld());
+	
+	// [mrmike] - Post-press fix. This was not correct! subtracting the parents's position from the kidPos
+	//            created a HUGE radius, depending on the location of the parent, which could be anywhere
+	//            in the game world.
+
+	//Vec3 dir = kidPos - m_Props.ToWorld().GetPosition();
+	//float newRadius = dir.Length() + kid->VGet()->Radius();
+	
+	float newRadius = glm::length(kidPos) + kid->VGet()->Radius(); 
+
+	if (newRadius > m_Props.m_Radius)
+		m_Props.m_Radius = newRadius;
+
+	return true;
+}
+
+//
+// SceneNode::VRemoveChild					- not in the book
+//
+//   If an actor is destroyed it should be removed from the scene graph.
+//   Generally the HumanView will recieve a message saying the actor has been
+//   destroyed, and it will then call Scene::RemoveChild which will traverse 
+//   the scene graph to find the child that needs removing.
+//
+bool SceneNode::VRemoveChild(ActorId id)
+{
+	for(SceneNodeList::iterator i=m_Children.begin(); i!=m_Children.end(); ++i)
+	{
+		const SceneNodeProperties* pProps = (*i)->VGet();
+		if(pProps->GetActorId() != INVALID_ACTOR_ID && id == pProps->GetActorId())
+		{
+			i = m_Children.erase(i);	//this can be expensive for vectors
+			return true;
+		}
+	}
+	return false;
+}
+
+
+
+////////////////////////////////////////////////////
+// RootNode Implementation
+////////////////////////////////////////////////////
+
+//
+// RootNode::RootNode					- Chapter 16, page 545
+//
+RootNode::RootNode()
+: SceneNode(INVALID_ACTOR_ID, WeakBaseRenderComponentPtr(), RenderPass_0, glm::mat4(1.0f))
+{
+	m_Children.reserve(RenderPass_Last);
+
+	std::shared_ptr<SceneNode> staticGroup(GCC_NEW SceneNode(INVALID_ACTOR_ID,  WeakBaseRenderComponentPtr(),  RenderPass_Static, glm::mat4(1.0f)));
+	m_Children.push_back(staticGroup);	// RenderPass_Static = 0
+
+	std::shared_ptr<SceneNode> actorGroup(GCC_NEW SceneNode(INVALID_ACTOR_ID,  WeakBaseRenderComponentPtr(),  RenderPass_Actor, glm::mat4(1.0f)));
+	m_Children.push_back(actorGroup);	// RenderPass_Actor = 1
+
+	std::shared_ptr<SceneNode> skyGroup(GCC_NEW SceneNode(INVALID_ACTOR_ID,  WeakBaseRenderComponentPtr(),  RenderPass_Sky, glm::mat4(1.0f)));
+	m_Children.push_back(skyGroup);	// RenderPass_Sky = 2
+
+	std::shared_ptr<SceneNode> invisibleGroup(GCC_NEW SceneNode(INVALID_ACTOR_ID,  WeakBaseRenderComponentPtr(),  RenderPass_NotRendered, glm::mat4(1.0f)));
+	m_Children.push_back(invisibleGroup);	// RenderPass_NotRendered = 3
+}
+
+//
+// RootNode::VAddChild					- Chapter 16, page 546
+//
+bool RootNode::VAddChild(std::shared_ptr<ISceneNode> kid)
+{
+	// The Root node has children that divide the scene graph into render passes.
+	// Scene nodes will get added to these children based on the value of the
+	// render pass member variable.
+
+	RenderPass pass = kid->VGet()->GetRenderPass();
+	if ((unsigned)pass >= m_Children.size() || !m_Children[pass])
+	{
+		GCC_ASSERT(0 && "There is no such render pass");
+		return false;
+	}
+
+	return m_Children[pass]->VAddChild(kid);
+}
+
+//
+// RootNode::VRemoveChild						- not described in the book 
+//
+//   Returns false if nothing was removed
+//
+bool RootNode::VRemoveChild(ActorId id)
+{
+	bool anythingRemoved = false;
+	for(int i=RenderPass_0; i<RenderPass_Last; ++i)
+	{
+		if(m_Children[i]->VRemoveChild(id))
+		{
+			anythingRemoved = true;
+		}
+	}
+	return anythingRemoved;
+}
+
+//
+// RootNode::VRenderChildren					- Chapter 16, page 547
+//
+int RootNode::VRenderChildren(Scene *pScene)
+{
+	// This code creates fine control of the render passes.
+
+	for (int pass = RenderPass_0; pass < RenderPass_Last; ++pass)
+	{
+		switch(pass)
+		{
+			case RenderPass_Static:
+			case RenderPass_Actor:
+				m_Children[pass]->VRenderChildren(pScene);
+				break;
+
+			case RenderPass_Sky:
+			{
+				std::shared_ptr<IRenderState> skyPass = pScene->GetRenderer()->VPrepareSkyBoxPass();
+				m_Children[pass]->VRenderChildren(pScene);
+				break;
+			}
+		}
+	}
+
+	return 0;
+}
+
+
+////////////////////////////////////////////////////
+// CameraNode Implementation
+////////////////////////////////////////////////////
+
+
+//
+// CameraNode::VRender					- Chapter 16, page 550
+//
+int CameraNode::VRender(Scene *pScene)
+{
+	if (m_DebugCamera)
+	{
+		// m_Frustum.Render();
+	}
+
+	return 1;
+}
+
+//
+// CameraNode::VOnRestore				- Chapter 16, page 550
+//
+int CameraNode::VOnRestore(Scene *pScene)
+{
+	Point p = g_pApp->GetScreenSize();
+	m_Frustum.SetAspect((float) p.x / (float) p.y);
+	m_Projection = glm::perspective(
+		m_Frustum.m_Fov,
+		m_Frustum.m_Aspect,
+		m_Frustum.m_Near,
+		m_Frustum.m_Far
+	);
+
+	// [munnellg] this isn't necessary, but we'll do it to
+	// preserve book code
+	pScene->GetRenderer()->VSetProjectionTransform(m_Projection);
+	return 0;
+}
+
+//
+// CameraNode::SetView					- Chapter 16, page 550
+//
+//    Note: this is incorrectly called CameraNode::SetView in the book
+//
+int CameraNode::SetViewTransform(Scene *pScene)
+{
+	// TODO(munnellg) - implement
+	// If there is a target, make sure the camera is
+	// rigidly attached right behind the target
+	if(m_pTarget)
+	{
+		glm::mat4 mat = m_pTarget->VGet()->ToWorld();
+		glm::vec4 at = m_CamOffsetVector;
+		glm::vec4 atWorld = mat * at;
+		glm::vec3 pos = geometry::GetPosition(mat) + glm::vec3(atWorld);
+		geometry::SetPosition(mat, pos);
+		VSetTransform(mat);
+	}
+
+	m_View = VGet()->FromWorld();
+
+	// [munnellg] this isn't necessary, but we'll do it to
+	// preserve book code
+	pScene->GetRenderer()->VSetViewTransform(m_View);
+	return 0;
+}
+
+//
+// CameraNode::GetWorldViewProjection			- not described in the book
+//
+//    Returns the concatenation of the world and view projection, which is generally sent into vertex shaders
+//
+glm::mat4 CameraNode::GetWorldViewProjection(Scene *pScene)
+{
+	glm::mat4 world = pScene->GetTopMatrix();
+	glm::mat4 view = VGet()->FromWorld();
+	return m_Projection * view * world;
+}
+
+
+
+////////////////////////////////////////////////////
+// D3DGrid9 Implementation
+//
+// D3D9 classes are not covered in the 4th edition. They are included here for those 
+// people that don't have D3D11 compatible video cards. 
+//
+// The code is somewhat similar to the D3DGrid11 class, which IS discussed in Chapter 16 
+// of the 4th edition.
+// 
+////////////////////////////////////////////////////
+
+OpenGLGrid::OpenGLGrid(ActorId actorId, WeakBaseRenderComponentPtr renderComponent, const glm::mat4 pMatrix)
+	: SceneNode(actorId, renderComponent, RenderPass_0, pMatrix)
+{
+	m_bTextureHasAlpha = false;
+	m_numIndices = 0;
+	m_vbo = 0;
+	m_vao = 0;
+	m_ebo = 0;
+}
+
+OpenGLGrid::~OpenGLGrid()
+{
+	glDeleteVertexArrays(1, &m_vao);
+	glDeleteBuffers(1, &m_vbo);
+	glDeleteBuffers(1, &m_ebo);
+}
+
+int OpenGLGrid::VOnRestore(Scene *pScene)
+{
+	// clear out any existing buffers
+	glDeleteVertexArrays(1, &m_vao);
+	glDeleteBuffers(1, &m_vbo);
+	glDeleteBuffers(1, &m_ebo);
+
+	// TODO(munnellg) - these VOnRestore calls need to have their results checked
+	SceneNode::VOnRestore(pScene);
+
+	// TODO(munnellg) - release shaders if allocating before creating shader so we don't leak memory
+	m_ShaderProgram.OnRestore(pScene);
+
+	GridRenderComponent* grc = static_cast<GridRenderComponent*>(m_RenderComponent);
+	int squares = grc->GetDivision();
+
+	SetRadius(sqrt(squares * squares / 2.0f) );
+
+	// Create the vertex buffer - we'll need enough verts
+	// to populate the grid. If we want a 2x2 grid, we'll
+	// need 3x3 set of verts.
+	m_numVerts = (squares+1)*(squares+1);	// Create vertex buffer
+
+	// Fill the vertex buffer. We are setting the tu and tv texture
+    // coordinates, which range from 0.0 to 1.0
+    VertexUnlitTextured *pVerts = GCC_NEW VertexUnlitTextured[m_numVerts];
+    GCC_ASSERT(pVerts && "Out of memory in OpenGLGrid::VOnRestore");
+    if (!pVerts)
+    	return 1;
+
+    for( int j=0; j<(squares+1); j++ )
+    {
+    	for (int i=0; i<(squares+1); i++)
+    	{
+    		// Which vertex are we setting?
+    		int index = i + (j * (squares+1) );
+    		VertexUnlitTextured *vert = &pVerts[index];
+
+    		// Default position of the grid is centered on the origin flat on
+    		// the XZ plane
+    		float x = (float)i - (squares/2.0f);
+    		float y = (float)j - (squares/2.0f);
+    		vert->Pos = glm::vec3(x,0.f,y);
+    		vert->Normal = glm::vec3(0.0f, 1.0f, 0.0f);
+
+    		// The texture coordinates are set to x,y to make the 
+    		// texture tile along with units - 1.0, 2.0, 3.0, etc
+    		vert->Uv.x       = x;
+    		vert->Uv.y       = y;
+    	}
+    }
+
+    // The number of indicies equals the number of polygons times 3
+	// since there are 3 indicies per polygon. Each grid square contains
+	// two polygons. The indicies are 16 bit, since our grids won't
+	// be that big!
+
+	m_numPolys = squares * squares * 2;
+
+	m_numIndices = m_numPolys * 3;
+	GLuint *pIndices = GCC_NEW GLuint[m_numIndices];
+
+	GCC_ASSERT(pIndices && "Out of memory in OpenGLGrid::VOnRestore");
+	if (!pIndices)
+	{
+		delete[] pVerts;
+		return 1;
+	}
+
+	// Loop through the grid squares and calc the values
+	// of each index. Each grid square has two triangles:
+	//
+	//		A - B
+	//		| / |
+	//		C - D
+
+	
+	GLuint *current = pIndices;
+	for( int j=0; j<squares; j++ )
+	{
+		for (int i=0; i<squares; i++)
+		{
+			// Triangle #1 ACB
+			*(current) = GLuint(i + (j*(squares+1)));
+			*(current+1) = GLuint(i + ((j+1)*(squares+1)));
+			*(current+2) = GLuint((i+1) + (j*(squares+1)));
+
+			*(current+3) = GLuint((i+1) + (j*(squares+1)));
+			*(current+4) = GLuint(i + ((j+1)*(squares+1)));
+			*(current+5) = GLuint((i+1) + ((j+1)*(squares+1)));
+			current += 6;
+		}
+	}
+
+	glCreateVertexArrays(1, &m_vao);
+
+	glCreateBuffers(1, &m_vbo);
+	glNamedBufferStorage(m_vbo, sizeof(VertexUnlitTextured) * m_numVerts, pVerts, 0);
+
+	glVertexArrayVertexBuffer(m_vao, 0, m_vbo, 0, sizeof(VertexUnlitTextured));
+
+	glEnableVertexArrayAttrib(m_vao, 0);
+	glVertexArrayAttribFormat(m_vao, 0, 3, GL_FLOAT, GL_FALSE, 0);
+	glVertexArrayAttribBinding(m_vao, 0, 0);
+
+	glEnableVertexArrayAttrib(m_vao, 1);
+	glVertexArrayAttribFormat(m_vao, 1, 3, GL_FLOAT, GL_FALSE, offsetof(VertexUnlitTextured, Normal));
+	glVertexArrayAttribBinding(m_vao, 1, 0);
+
+	glEnableVertexArrayAttrib(m_vao, 2);
+	glVertexArrayAttribFormat(m_vao, 2, 2, GL_FLOAT, GL_FALSE,  offsetof(VertexUnlitTextured, Uv));
+	glVertexArrayAttribBinding(m_vao, 2, 0);
+	
+	delete[] pVerts;
+
+	glCreateBuffers(1, &m_ebo);
+	glNamedBufferStorage(m_ebo, sizeof(GLuint) * m_numIndices, pIndices, 0);
+	glVertexArrayElementBuffer(m_vao, m_ebo);
+
+	delete[] pIndices;
+
+	return 0;
+}
+
+int OpenGLGrid::VRender(Scene *pScene)
+{
+	GridRenderComponent* grc = static_cast<GridRenderComponent*>(m_RenderComponent);
+	m_ShaderProgram.SetTexture(grc->GetTextureResource());
+	m_ShaderProgram.SetupRender(pScene, this);
+
+	glBindVertexArray(m_vao);
+	glDrawElements(GL_TRIANGLES, m_numIndices, GL_UNSIGNED_INT, 0);
+	glBindVertexArray(0);
+
+	return 0;
+}

Vissa filer visades inte eftersom för många filer har ändrats