Repl.cs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. using System;
  2. using System.IO;
  3. using System.Threading.Tasks;
  4. using Urho.Actions;
  5. using Urho.Gui;
  6. using Urho.Shapes;
  7. namespace Urho.Repl
  8. {
  9. public class Simple3DScene : Application
  10. {
  11. public Simple3DScene(ApplicationOptions options) : base(options) {}
  12. public static Task<Simple3DScene> RunAsync(int width = 600, int height = 500)
  13. {
  14. var taskSource = new TaskCompletionSource<Simple3DScene>();
  15. Action callback = null;
  16. callback = () => {
  17. Started -= callback;
  18. taskSource.TrySetResult(Current as Simple3DScene);
  19. };
  20. Environment.CurrentDirectory = Path.GetDirectoryName(typeof(Simple3DScene).Assembly.Location);
  21. if (!File.Exists("CoreData.pak")) {
  22. using (Stream input = typeof(Simple3DScene).Assembly.GetManifestResourceStream("Urho.CoreData.pak"))
  23. using (Stream output = File.Create(Path.Combine("CoreData.pak")))
  24. input.CopyTo(output);
  25. }
  26. Directory.CreateDirectory("Data");
  27. Started += callback;
  28. Task.Delay(1).ContinueWith(r => new Simple3DScene(
  29. new ApplicationOptions(assetsFolder: "Data") {
  30. Width = width,
  31. Height = height
  32. }).Run(), TaskContinuationOptions.ExecuteSynchronously);
  33. return taskSource.Task;
  34. }
  35. public Node CameraNode { get; private set; }
  36. public Camera Camera { get; private set; }
  37. public Scene Scene { get; private set; }
  38. public Octree Octree { get; private set; }
  39. public Node RootNode { get; private set; }
  40. public Node LightNode { get; private set; }
  41. public Light Light { get; private set; }
  42. public Viewport Viewport { get; private set; }
  43. public bool MoveCamera { get; set; }
  44. public float Yaw { get; set; }
  45. public float Pitch { get; set; }
  46. //NOTE: currently working only in 64bit
  47. public unsafe void SetBackgroundColor(Color color)
  48. {
  49. var rp = Viewport.RenderPath;
  50. for (int i = 0; i < rp.NumCommands; i++)
  51. {
  52. var cmd = rp.GetCommand((uint) i);
  53. if (cmd->Type == RenderCommandType.Clear)
  54. {
  55. cmd->UseFogColor = 0;
  56. cmd->ClearColor = color;
  57. }
  58. }
  59. }
  60. public Node AddShape<T>(Color color) where T : Shape
  61. {
  62. var child = RootNode.CreateChild();
  63. var shape = child.CreateComponent<T>();
  64. shape.Color = color;
  65. return child;
  66. }
  67. protected override void Start()
  68. {
  69. // 3D scene with Octree
  70. Scene = new Scene(Context);
  71. Octree = Scene.CreateComponent<Octree>();
  72. RootNode = Scene.CreateChild("RootNode");
  73. RootNode.Position = new Vector3(x: 0, y: 0, z: 8);
  74. LightNode = Scene.CreateChild("DirectionalLight");
  75. LightNode.SetDirection(new Vector3(0.5f, 0.0f, 0.8f));
  76. Light = LightNode.CreateComponent<Light>();
  77. Light.LightType = LightType.Directional;
  78. Light.CastShadows = true;
  79. Light.ShadowBias = new BiasParameters(0.00025f, 0.5f);
  80. Light.ShadowCascade = new CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f);
  81. Light.SpecularIntensity = 0.5f;
  82. Light.Color = new Color(1.2f, 1.2f, 1.2f);
  83. // Camera
  84. CameraNode = Scene.CreateChild(name: "camera");
  85. Camera = CameraNode.CreateComponent<Camera>();
  86. // Viewport
  87. Viewport = new Viewport(Context, Scene, Camera, null);
  88. Renderer.SetViewport(0, Viewport);
  89. SetBackgroundColor(Color.White);
  90. // Subscribe to Esc key:
  91. Input.SubscribeToKeyDown(args => { if (args.Key == Key.Esc) Engine.Exit(); });
  92. }
  93. protected override void OnUpdate(float timeStep)
  94. {
  95. if (MoveCamera)
  96. SimpleMoveCamera3D(timeStep);
  97. base.OnUpdate(timeStep);
  98. }
  99. protected void SimpleMoveCamera3D(float timeStep, float moveSpeed = 10.0f)
  100. {
  101. const float mouseSensitivity = .05f;
  102. if (UI.FocusElement != null)
  103. return;
  104. var mouseMove = Input.MouseMove;
  105. Yaw += mouseSensitivity * mouseMove.X;
  106. Pitch += mouseSensitivity * mouseMove.Y;
  107. Pitch = MathHelper.Clamp(Pitch, -90, 90);
  108. CameraNode.Rotation = new Quaternion(Pitch, Yaw, 0);
  109. if (Input.GetKeyDown(Key.W)) CameraNode.Translate(Vector3.UnitZ * moveSpeed * timeStep);
  110. if (Input.GetKeyDown(Key.S)) CameraNode.Translate(-Vector3.UnitZ * moveSpeed * timeStep);
  111. if (Input.GetKeyDown(Key.A)) CameraNode.Translate(-Vector3.UnitX * moveSpeed * timeStep);
  112. if (Input.GetKeyDown(Key.D)) CameraNode.Translate(Vector3.UnitX * moveSpeed * timeStep);
  113. }
  114. }
  115. public class Bar : Component
  116. {
  117. Node barNode;
  118. Node textNode;
  119. Color color;
  120. string name;
  121. public float Value
  122. {
  123. get { return barNode.Scale.Y; }
  124. set { barNode.RunActionsAsync(new EaseBackOut(new ScaleTo(3f, 1, value, 1))); }
  125. }
  126. public Bar(string name, Color color)
  127. {
  128. this.name = name;
  129. this.color = color;
  130. ReceiveSceneUpdates = true;
  131. }
  132. public override void OnAttachedToNode(Node node)
  133. {
  134. barNode = node.CreateChild();
  135. barNode.Scale = new Vector3(1, 0, 1);
  136. var box = barNode.CreateComponent<Box>();
  137. box.Color = color;
  138. textNode = node.CreateChild();
  139. textNode.Position = new Vector3(0, 3, 0);
  140. var text3D = textNode.CreateComponent<Text3D>();
  141. text3D.SetFont(Application.ResourceCache.GetFont("Fonts/Anonymous Pro.ttf"), 60);
  142. text3D.TextEffect = TextEffect.Stroke;
  143. text3D.Text = name;
  144. base.OnAttachedToNode(node);
  145. }
  146. protected override void OnUpdate(float timeStep)
  147. {
  148. var pos = barNode.Position;
  149. var scale = barNode.Scale;
  150. barNode.Position = new Vector3(pos.X, scale.Y / 2f, pos.Z);
  151. textNode.Position = new Vector3(-0.5f, scale.Y + 0.5f, 0);
  152. }
  153. }
  154. }