TestScene.as 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. Scene@ testScene;
  2. Camera@ camera;
  3. Node@ cameraNode;
  4. float yaw = 0.0;
  5. float pitch = 0.0;
  6. int drawDebug = 0;
  7. void Start()
  8. {
  9. if (engine.headless)
  10. {
  11. ErrorDialog("TestScene", "Headless mode is not supported. The program will now exit.");
  12. engine.Exit();
  13. return;
  14. }
  15. InitConsole();
  16. InitUI();
  17. InitScene();
  18. SubscribeToEvent("Update", "HandleUpdate");
  19. SubscribeToEvent("KeyDown", "HandleKeyDown");
  20. SubscribeToEvent("MouseMove", "HandleMouseMove");
  21. SubscribeToEvent("MouseButtonDown", "HandleMouseButtonDown");
  22. SubscribeToEvent("MouseButtonUp", "HandleMouseButtonUp");
  23. SubscribeToEvent("PostRenderUpdate", "HandlePostRenderUpdate");
  24. }
  25. void InitConsole()
  26. {
  27. XMLFile@ uiStyle = cache.GetResource("XMLFile", "UI/DefaultStyle.xml");
  28. engine.CreateDebugHud();
  29. debugHud.style = uiStyle;
  30. debugHud.mode = DEBUGHUD_SHOW_ALL;
  31. engine.CreateConsole();
  32. console.style = uiStyle;
  33. }
  34. void InitUI()
  35. {
  36. XMLFile@ uiStyle = cache.GetResource("XMLFile", "UI/DefaultStyle.xml");
  37. Cursor@ newCursor = Cursor("Cursor");
  38. newCursor.style = uiStyle;
  39. newCursor.position = IntVector2(graphics.width / 2, graphics.height / 2);
  40. ui.cursor = newCursor;
  41. }
  42. void InitScene()
  43. {
  44. testScene = Scene("TestScene");
  45. PhysicsWorld@ world = testScene.CreateComponent("PhysicsWorld");
  46. testScene.CreateComponent("Octree");
  47. testScene.CreateComponent("DebugRenderer");
  48. world.gravity = Vector3(0.0, -9.81, 0.0);
  49. world.fps = 100;
  50. world.linearRestThreshold = 0.1;
  51. world.angularRestThreshold = 0.1;
  52. world.contactSurfaceLayer = 0.001;
  53. Zone@ zone = testScene.CreateComponent("Zone");
  54. zone.ambientColor = Color(0.1, 0.1, 0.1);
  55. zone.fogColor = Color(0.5, 0.5, 0.7);
  56. zone.fogStart = 100.0;
  57. zone.fogEnd = 300.0;
  58. zone.boundingBox = BoundingBox(-1000.0, 1000.0);
  59. {
  60. Node@ objectNode = testScene.CreateChild("Floor");
  61. objectNode.position = Vector3(0.0, -0.5, 0.0);
  62. objectNode.scale = Vector3(100.0, 0.5, 100.0);
  63. StaticModel@ object = objectNode.CreateComponent("StaticModel");
  64. object.model = cache.GetResource("Model", "Models/Box.mdl");
  65. object.material = cache.GetResource("Material", "Materials/Test.xml");
  66. object.occluder = true;
  67. CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
  68. shape.SetBox(Vector3(2.0, 2.0, 2.0), Vector3(), Quaternion());
  69. shape.collisionGroup = 2;
  70. shape.collisionMask = 1;
  71. }
  72. for (uint i = 0; i < 50; ++i)
  73. {
  74. Node@ objectNode = testScene.CreateChild("Box");
  75. objectNode.position = Vector3(Random(180.0) - 90.0, 1.0, Random(180.0) - 90.0);
  76. StaticModel@ object = objectNode.CreateComponent("StaticModel");
  77. object.model = cache.GetResource("Model", "Models/Box.mdl");
  78. object.material = cache.GetResource("Material", "Materials/Test.xml");
  79. object.castShadows = true;
  80. CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
  81. shape.SetBox(Vector3(2.0, 2.0, 2.0), Vector3(), Quaternion());
  82. shape.collisionGroup = 2;
  83. shape.collisionMask = 1;
  84. }
  85. for (uint i = 0; i < 10; ++i)
  86. {
  87. Node@ objectNode = testScene.CreateChild("Box");
  88. objectNode.position = Vector3(Random(180.0) - 90.0, 10.0, Random(180.0) - 90.0);
  89. objectNode.SetScale(10.0);
  90. StaticModel@ object = objectNode.CreateComponent("StaticModel");
  91. object.model = cache.GetResource("Model", "Models/Box.mdl");
  92. object.material = cache.GetResource("Material", "Materials/Test.xml");
  93. object.castShadows = true;
  94. object.occluder = true;
  95. CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
  96. shape.SetBox(Vector3(2.0, 2.0, 2.0), Vector3(), Quaternion());
  97. shape.collisionGroup = 2;
  98. shape.collisionMask = 1;
  99. }
  100. for (uint i = 0; i < 50; ++i)
  101. {
  102. Node@ objectNode = testScene.CreateChild("Mushroom");
  103. objectNode.position = Vector3(Random(180.0) - 90.0, 0.0, Random(180.0) - 90.0);
  104. objectNode.rotation = Quaternion(0.0, Random(360.0), 0.0);
  105. objectNode.SetScale(5.0);
  106. StaticModel@ object = objectNode.CreateComponent("StaticModel");
  107. object.model = cache.GetResource("Model", "Models/Mushroom.mdl");
  108. object.material = cache.GetResource("Material", "Materials/Mushroom.xml");
  109. object.castShadows = true;
  110. CollisionShape@ shape = objectNode.CreateComponent("CollisionShape");
  111. shape.SetTriangleMesh(cache.GetResource("Model", "Models/Mushroom.mdl"), 0, Vector3(), Quaternion());
  112. shape.collisionGroup = 2;
  113. shape.collisionMask = 1;
  114. }
  115. for (uint i = 0; i < 50; ++i)
  116. {
  117. Node@ objectNode = testScene.CreateChild("Jack");
  118. objectNode.position = Vector3(Random(180.0) - 90.0, 0.0, Random(180.0) - 90.0);
  119. objectNode.rotation = Quaternion(0.0, Random(360.0), 0.0);
  120. AnimatedModel@ object = objectNode.CreateComponent("AnimatedModel");
  121. object.model = cache.GetResource("Model", "Models/Jack.mdl");
  122. object.material = cache.GetResource("Material", "Materials/Jack.xml");
  123. object.castShadows = true;
  124. AnimationController@ ctrl = objectNode.CreateComponent("AnimationController");
  125. ctrl.Play("Models/Jack_Walk.ani", 0, true, 0.0f);
  126. }
  127. {
  128. Node@ lightNode = testScene.CreateChild("Light");
  129. lightNode.direction = Vector3(0.5, -0.5, 0.5);
  130. Light@ light = lightNode.CreateComponent("Light");
  131. light.lightType = LIGHT_DIRECTIONAL;
  132. light.castShadows = true;
  133. light.shadowBias = BiasParameters(0.0001, 0.5);
  134. light.shadowCascade = CascadeParameters(3, 0.90, 0.2, 200.0);
  135. light.specularIntensity = 0.5f;
  136. }
  137. // Enable access to this script file & scene from the console
  138. script.defaultScene = testScene;
  139. script.defaultScriptFile = scriptFile;
  140. // Create the camera outside the scene so it is unaffected by scene load/save
  141. cameraNode = Node();
  142. camera = cameraNode.CreateComponent("Camera");
  143. cameraNode.position = Vector3(0, 2, 0);
  144. renderer.viewports[0] = Viewport(testScene, camera);
  145. }
  146. void HandleUpdate(StringHash eventType, VariantMap& eventData)
  147. {
  148. float timeStep = eventData["TimeStep"].GetFloat();
  149. if (ui.focusElement is null)
  150. {
  151. float speedMultiplier = 1.0;
  152. if (input.keyDown[KEY_SHIFT])
  153. speedMultiplier = 5.0;
  154. if (input.keyDown[KEY_CTRL])
  155. speedMultiplier = 0.1;
  156. if (input.keyDown['W'])
  157. cameraNode.TranslateRelative(Vector3(0, 0, 10) * timeStep * speedMultiplier);
  158. if (input.keyDown['S'])
  159. cameraNode.TranslateRelative(Vector3(0, 0, -10) * timeStep * speedMultiplier);
  160. if (input.keyDown['A'])
  161. cameraNode.TranslateRelative(Vector3(-10, 0, 0) * timeStep * speedMultiplier);
  162. if (input.keyDown['D'])
  163. cameraNode.TranslateRelative(Vector3(10, 0, 0) * timeStep * speedMultiplier);
  164. if (input.keyPress['1'])
  165. {
  166. int nextRenderMode = graphics.renderMode;
  167. if (input.keyDown[KEY_SHIFT])
  168. {
  169. --nextRenderMode;
  170. if (nextRenderMode < 0)
  171. nextRenderMode = 2;
  172. }
  173. else
  174. {
  175. ++nextRenderMode;
  176. if (nextRenderMode > 2)
  177. nextRenderMode = 0;
  178. }
  179. graphics.SetMode(RenderMode(nextRenderMode));
  180. }
  181. if (input.keyPress['2'])
  182. {
  183. int quality = renderer.textureQuality;
  184. ++quality;
  185. if (quality > 2)
  186. quality = 0;
  187. renderer.textureQuality = quality;
  188. }
  189. if (input.keyPress['3'])
  190. {
  191. int quality = renderer.materialQuality;
  192. ++quality;
  193. if (quality > 2)
  194. quality = 0;
  195. renderer.materialQuality = quality;
  196. }
  197. if (input.keyPress['4'])
  198. renderer.specularLighting = !renderer.specularLighting;
  199. if (input.keyPress['5'])
  200. renderer.drawShadows = !renderer.drawShadows;
  201. if (input.keyPress['6'])
  202. {
  203. int size = renderer.shadowMapSize;
  204. size *= 2;
  205. if (size > 2048)
  206. size = 512;
  207. renderer.shadowMapSize = size;
  208. }
  209. if (input.keyPress['7'])
  210. renderer.shadowMapHiresDepth = !renderer.shadowMapHiresDepth;
  211. if (input.keyPress['8'])
  212. {
  213. bool occlusion = renderer.maxOccluderTriangles > 0;
  214. occlusion = !occlusion;
  215. renderer.maxOccluderTriangles = occlusion ? 5000 : 0;
  216. }
  217. if (input.keyPress['9'])
  218. renderer.dynamicInstancing = !renderer.dynamicInstancing;
  219. if (input.keyPress[' '])
  220. {
  221. drawDebug++;
  222. if (drawDebug > 2)
  223. drawDebug = 0;
  224. }
  225. if (input.keyPress['C'])
  226. camera.orthographic = !camera.orthographic;
  227. if (input.keyPress['T'])
  228. debugHud.Toggle(DEBUGHUD_SHOW_PROFILER);
  229. if (input.keyPress[KEY_F5])
  230. {
  231. File@ xmlFile = File("scene.xml", FILE_WRITE);
  232. testScene.SaveXML(xmlFile);
  233. }
  234. if (input.keyPress[KEY_F7])
  235. {
  236. File@ xmlFile = File("scene.xml", FILE_READ);
  237. if (xmlFile.open)
  238. testScene.LoadXML(xmlFile);
  239. }
  240. }
  241. if (input.keyPress[KEY_ESC])
  242. {
  243. if (ui.focusElement is null)
  244. engine.Exit();
  245. else
  246. console.visible = false;
  247. }
  248. }
  249. void HandleKeyDown(StringHash eventType, VariantMap& eventData)
  250. {
  251. // Check for toggling the console
  252. if (eventData["Key"].GetInt() == 220)
  253. {
  254. console.Toggle();
  255. input.SuppressNextChar();
  256. }
  257. }
  258. void HandleMouseMove(StringHash eventType, VariantMap& eventData)
  259. {
  260. if (eventData["Buttons"].GetInt() & MOUSEB_RIGHT != 0)
  261. {
  262. int mousedx = eventData["DX"].GetInt();
  263. int mousedy = eventData["DY"].GetInt();
  264. yaw += mousedx / 10.0f;
  265. pitch += mousedy / 10.0f;
  266. if (pitch < -90.0f)
  267. pitch = -90.0f;
  268. if (pitch > 90.0f)
  269. pitch = 90.0f;
  270. cameraNode.rotation = Quaternion(pitch, yaw, 0);
  271. }
  272. }
  273. void HandleMouseButtonDown(StringHash eventType, VariantMap& eventData)
  274. {
  275. int button = eventData["Button"].GetInt();
  276. if (button == MOUSEB_RIGHT)
  277. ui.cursor.visible = false;
  278. // Test creating a new physics object
  279. if ((button == MOUSEB_LEFT) && (ui.GetElementAt(ui.cursorPosition, true) is null) && (ui.focusElement is null))
  280. {
  281. Node@ newNode = testScene.CreateChild();
  282. newNode.position = cameraNode.position;
  283. newNode.rotation = cameraNode.rotation;
  284. newNode.SetScale(0.1);
  285. CollisionShape@ shape = newNode.CreateComponent("CollisionShape");
  286. shape.SetBox(Vector3(2, 2, 2), Vector3(), Quaternion());
  287. shape.friction = 1.0;
  288. shape.collisionGroup = 1;
  289. shape.collisionMask = 3;
  290. RigidBody@ body = newNode.CreateComponent("RigidBody");
  291. body.angularMaxVelocity = 500.0;
  292. body.linearVelocity = camera.upVector + camera.forwardVector * 10.0;
  293. body.mass = 1;
  294. StaticModel@ object = newNode.CreateComponent("StaticModel");
  295. object.model = cache.GetResource("Model", "Models/Box.mdl");
  296. object.material = cache.GetResource("Material", "Materials/Test.xml");
  297. object.castShadows = true;
  298. object.shadowDistance = 150.0;
  299. object.drawDistance = 200.0;
  300. }
  301. }
  302. void HandleMouseButtonUp(StringHash eventType, VariantMap& eventData)
  303. {
  304. if (eventData["Button"].GetInt() == MOUSEB_RIGHT)
  305. ui.cursor.visible = true;
  306. }
  307. void HandlePostRenderUpdate()
  308. {
  309. // Draw rendering debug geometry without depth test to see the effect of occlusion
  310. if (drawDebug == 1)
  311. renderer.DrawDebugGeometry(false);
  312. if (drawDebug == 2)
  313. testScene.physicsWorld.DrawDebugGeometry(true);
  314. IntVector2 pos = ui.cursorPosition;
  315. if (ui.GetElementAt(pos, true) is null)
  316. {
  317. Ray cameraRay = camera.GetScreenRay(float(pos.x) / graphics.width, float(pos.y) / graphics.height);
  318. Array<RayQueryResult> result = testScene.octree.Raycast(cameraRay, DRAWABLE_GEOMETRY, 250.0, RAY_TRIANGLE);
  319. if (result.length > 0)
  320. {
  321. Drawable@ object = result[0].drawable;
  322. Vector3 rayHitPos = cameraRay.origin + cameraRay.direction * result[0].distance;
  323. testScene.debugRenderer.AddBoundingBox(BoundingBox(rayHitPos + Vector3(-0.01, -0.01, -0.01), rayHitPos +
  324. Vector3(0.01, 0.01, 0.01)), Color(1.0, 1.0, 1.0), true);
  325. }
  326. }
  327. }