SceneItem.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // SceneItem.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Text;
  13. using Microsoft.Xna.Framework;
  14. using Microsoft.Xna.Framework.Graphics;
  15. #endregion
  16. namespace Spacewar
  17. {
  18. /// <summary>
  19. /// SceneItem is any item that can be in a scenegraph
  20. /// </summary>
  21. public class SceneItem : List<SceneItem>
  22. {
  23. /// <summary>
  24. /// Collision Radius of this item
  25. /// </summary>
  26. protected float radius;
  27. /// <summary>
  28. /// Should this item be deleted?
  29. /// </summary>
  30. protected bool delete;
  31. /// <summary>
  32. /// Simulation paused for this items, nothing will update
  33. /// </summary>
  34. private bool paused;
  35. /// <summary>
  36. /// The root SceneItem
  37. /// </summary>
  38. protected SceneItem Root;
  39. /// <summary>
  40. /// The parent SceneItem
  41. /// </summary>
  42. protected SceneItem Parent;
  43. /// <summary>
  44. /// Shape is the actual renderable object
  45. /// </summary>
  46. protected Shape shape;
  47. /// <summary>
  48. /// The position of this item
  49. /// </summary>
  50. protected Vector3 position;
  51. /// <summary>
  52. /// The velocity of this item
  53. /// </summary>
  54. protected Vector3 velocity;
  55. /// <summary>
  56. /// The acceleration of the item
  57. /// </summary>
  58. protected Vector3 acceleration;
  59. /// <summary>
  60. /// The current rotation of this item
  61. /// </summary>
  62. protected Vector3 rotation;
  63. /// <summary>
  64. /// The scaling transformation for this object
  65. /// </summary>
  66. protected Vector3 scale = new Vector3(1f, 1f, 1f);
  67. /// <summary>
  68. /// The center of rotation and scaling
  69. /// </summary>
  70. protected Vector3 center;
  71. private Game game;
  72. #region Properties
  73. public bool Delete
  74. {
  75. get
  76. {
  77. return delete;
  78. }
  79. set
  80. {
  81. delete = value;
  82. }
  83. }
  84. public float Radius
  85. {
  86. get
  87. {
  88. return radius;
  89. }
  90. set
  91. {
  92. radius = value;
  93. }
  94. }
  95. public Shape ShapeItem
  96. {
  97. get
  98. {
  99. return shape;
  100. }
  101. set
  102. {
  103. shape = value;
  104. }
  105. }
  106. public bool Paused
  107. {
  108. get
  109. {
  110. return paused;
  111. }
  112. set
  113. {
  114. paused = value;
  115. }
  116. }
  117. public Vector3 Acceleration
  118. {
  119. get
  120. {
  121. return acceleration;
  122. }
  123. }
  124. public Vector3 Velocity
  125. {
  126. get
  127. {
  128. return velocity;
  129. }
  130. set
  131. {
  132. velocity = value;
  133. }
  134. }
  135. public Vector3 Position
  136. {
  137. get
  138. {
  139. return position;
  140. }
  141. set
  142. {
  143. position = value;
  144. }
  145. }
  146. public Vector3 Rotation
  147. {
  148. get
  149. {
  150. return rotation;
  151. }
  152. set
  153. {
  154. rotation = value;
  155. }
  156. }
  157. public Vector3 Center
  158. {
  159. get
  160. {
  161. return center;
  162. }
  163. set
  164. {
  165. center = value;
  166. }
  167. }
  168. public Vector3 Scale
  169. {
  170. get
  171. {
  172. return scale;
  173. }
  174. set
  175. {
  176. scale = value;
  177. }
  178. }
  179. protected Game GameInstance
  180. {
  181. get
  182. {
  183. return game;
  184. }
  185. }
  186. #endregion
  187. /// <summary>
  188. /// Default constructor, does nothing special
  189. /// </summary>
  190. public SceneItem(Game game)
  191. {
  192. this.game = game;
  193. }
  194. /// <summary>
  195. /// Creates a SceneItem with a shape to be rendered at an initial position
  196. /// </summary>
  197. /// <param name="shape">The shape to be rendered for this item</param>
  198. /// <param name="initialPosition">The initial position of the item</param>
  199. public SceneItem(Game game, Shape shape, Vector3 initialPosition)
  200. {
  201. this.shape = shape;
  202. this.position = initialPosition;
  203. this.game = game;
  204. }
  205. /// <summary>
  206. /// Creates a SceneItem with a shape to be rendered
  207. /// </summary>
  208. /// <param name="shape">The shape to be rendered for this item</param>
  209. public SceneItem(Game game, Shape shape)
  210. {
  211. this.shape = shape;
  212. this.game = game;
  213. }
  214. /// <summary>
  215. /// Creates a SceneItem with no shape but a position
  216. /// </summary>
  217. /// <param name="initialPosition">The initial position of the item</param>
  218. public SceneItem(Game game, Vector3 initialPosition)
  219. {
  220. this.position = initialPosition;
  221. this.game = game;
  222. }
  223. /// <summary>
  224. /// Adds an item to the Scene Node
  225. /// </summary>
  226. /// <param name="childItem">The item to add</param>
  227. public new void Add(SceneItem childItem)
  228. {
  229. //A new custom 'add' that sets the parent and the root properties
  230. //on the child item
  231. childItem.Parent = this;
  232. if (Root == null)
  233. {
  234. childItem.Root = this;
  235. }
  236. else
  237. {
  238. childItem.Root = Root;
  239. }
  240. //Call the 'real' add method on the dictionary
  241. ((List<SceneItem>)this).Add(childItem);
  242. }
  243. /// <summary>
  244. /// Updates any values associated with this scene item and its children
  245. /// </summary>
  246. /// <param name="time">Game time</param>
  247. /// <param name="elapsedTime">Elapsed game time since last call</param>
  248. public virtual void Update(TimeSpan time, TimeSpan elapsedTime)
  249. {
  250. if (!paused)
  251. {
  252. //Do the basic acceleration/velocity/position updates
  253. velocity += Vector3.Multiply(acceleration, (float)elapsedTime.TotalSeconds);
  254. position += Vector3.Multiply(velocity, (float)elapsedTime.TotalSeconds);
  255. }
  256. //If this item has something to draw then update it
  257. if (shape != null)
  258. {
  259. shape.World = Matrix.CreateTranslation(-center) *
  260. Matrix.CreateScale(scale) *
  261. Matrix.CreateRotationX(rotation.X) *
  262. Matrix.CreateRotationY(rotation.Y) *
  263. Matrix.CreateRotationZ(rotation.Z) *
  264. Matrix.CreateTranslation(position + center);
  265. if (!paused)
  266. {
  267. shape.Update(time, elapsedTime);
  268. }
  269. }
  270. //Update each child item
  271. foreach (SceneItem item in this)
  272. {
  273. item.Update(time, elapsedTime);
  274. }
  275. //Remove any items that need deletion
  276. int i = 0;
  277. while (i < Count)
  278. {
  279. if (this[i].delete)
  280. {
  281. RemoveAt(i);
  282. }
  283. else
  284. {
  285. i++;
  286. }
  287. }
  288. //RemoveAll(IsDeleted);
  289. }
  290. private static bool IsDeleted(SceneItem item)
  291. {
  292. return item.delete;
  293. }
  294. /// <summary>
  295. /// Render any items associated with this scene item and its children
  296. /// </summary>
  297. public virtual void Render()
  298. {
  299. //If this item has something to draw then draw it
  300. if (shape != null)
  301. {
  302. shape.Render();
  303. }
  304. //Then render all of the child nodes
  305. foreach (SceneItem item in this)
  306. {
  307. item.Render();
  308. }
  309. }
  310. /// <summary>
  311. /// Checks if there is a collision between the this and the passed in item
  312. /// </summary>
  313. /// <param name="item">A scene item to check</param>
  314. /// <returns>True if there is a collision</returns>
  315. public virtual bool Collide(SceneItem item)
  316. {
  317. //Until we get collision meshes sorted just do a simple sphere (well circle!) check
  318. if ((position - item.position).Length() < radius + item.radius)
  319. return true;
  320. //If we are a ship and we are a long, thin pencil,
  321. //we have additional extents, check those, too!
  322. Ship shipItem = item as Ship;
  323. if (shipItem != null && shipItem.ExtendedExtent != null)
  324. {
  325. Matrix localRotation = Matrix.CreateRotationZ(shipItem.Rotation.Z);
  326. Vector4 extendedPosition = Vector4.Transform(shipItem.ExtendedExtent[0], localRotation);
  327. Vector3 localPosition = shipItem.Position + new Vector3(extendedPosition.X, extendedPosition.Y, extendedPosition.Z);
  328. if ((Position - localPosition).Length() < radius + item.Radius)
  329. return true;
  330. extendedPosition = Vector4.Transform(shipItem.ExtendedExtent[1], localRotation);
  331. localPosition = shipItem.Position + new Vector3(extendedPosition.X, extendedPosition.Y, extendedPosition.Z);
  332. if ((Position - localPosition).Length() < radius + item.Radius)
  333. return true;
  334. }
  335. Ship ship = this as Ship;
  336. if (ship != null && ship.ExtendedExtent != null)
  337. {
  338. Matrix localRotation = Matrix.CreateRotationZ(ship.Rotation.Z);
  339. Vector4 extendedPosition = Vector4.Transform(ship.ExtendedExtent[0], localRotation);
  340. Vector3 localPosition = ship.Position + new Vector3(extendedPosition.X, extendedPosition.Y, extendedPosition.Z);
  341. if ((localPosition - item.Position).Length() < radius + item.Radius)
  342. return true;
  343. extendedPosition = Vector4.Transform(ship.ExtendedExtent[1], localRotation);
  344. localPosition = ship.Position + new Vector3(extendedPosition.X, extendedPosition.Y, extendedPosition.Z);
  345. if ((localPosition - item.Position).Length() < radius + item.Radius)
  346. return true;
  347. }
  348. return false;
  349. }
  350. public virtual void OnCreateDevice()
  351. {
  352. }
  353. }
  354. }