Renderable.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. namespace BansheeEngine
  5. {
  6. /** @addtogroup Rendering
  7. * @{
  8. */
  9. /// <summary>
  10. /// Renderable represents any visible object in the scene. It has a mesh, bounds and a set of materials. Renderer will
  11. /// render any Renderable objects visible by a camera.
  12. /// </summary>
  13. [RunInEditor]
  14. public sealed class Renderable : Component
  15. {
  16. private NativeRenderable _native;
  17. [SerializeField]
  18. private SerializableData serializableData = new SerializableData();
  19. /// <summary>
  20. /// Returns the non-component version of Renderable that is wrapped by this component.
  21. /// </summary>
  22. internal NativeRenderable Native
  23. {
  24. get { return _native; }
  25. }
  26. /// <summary>
  27. /// Attaches an animation that will be used for animating the renderable's mesh.
  28. /// </summary>
  29. internal NativeAnimation NativeAnimation
  30. {
  31. set
  32. {
  33. if (_native != null)
  34. {
  35. _native.Animation = value;
  36. // Need to update transform because animated renderables handle local transforms through bones, so it
  37. // shouldn't be included in the renderable's transform.
  38. _native.UpdateTransform(SceneObject, true);
  39. }
  40. }
  41. }
  42. /// <summary>
  43. /// Mesh to render.
  44. /// </summary>
  45. public Mesh Mesh
  46. {
  47. get { return _native.Mesh; }
  48. set
  49. {
  50. _native.Mesh = value;
  51. serializableData.mesh = value;
  52. int subMeshCount = 0;
  53. if (value != null)
  54. subMeshCount = value.SubMeshCount;
  55. Material[] newMaterials = new Material[subMeshCount];
  56. int numToCopy = MathEx.Min(newMaterials.Length, serializableData.materials.Length);
  57. Array.Copy(serializableData.materials, newMaterials, numToCopy);
  58. serializableData.materials = newMaterials;
  59. }
  60. }
  61. /// <summary>
  62. /// Material to use when rendering the mesh. If the mesh contains multiple sub-meshes then you may set individual
  63. /// materials for each sub-mesh.
  64. /// </summary>
  65. public Material Material
  66. {
  67. get { return _native.GetMaterial(0); }
  68. set
  69. { _native.SetMaterial(value); serializableData.materials[0] = value; }
  70. }
  71. /// <summary>
  72. /// Materials to use when rendering the mesh.
  73. /// </summary>
  74. public Material[] Materials
  75. {
  76. get { return _native.Materials; }
  77. set
  78. {
  79. _native.Materials = value;
  80. serializableData.materials = new Material[value.Length];
  81. Array.Copy(value, serializableData.materials, value.Length);
  82. }
  83. }
  84. /// <summary>
  85. /// Returns a material for a specific sub-mesh.
  86. /// </summary>
  87. /// <param name="index">Index of the sub-mesh.</param>
  88. /// <returns>Material used for rendering the sub-mesh at the specified index.</returns>
  89. public Material GetMaterial(int index = 0)
  90. {
  91. return _native.GetMaterial(index);
  92. }
  93. /// <summary>
  94. /// Sets a material for a specific sub-mesh.
  95. /// </summary>
  96. /// <param name="material">Material to use for rendering the sub-mesh at the specified index.</param>
  97. /// <param name="index">Index of the sub-mesh.</param>
  98. public void SetMaterial(Material material, int index = 0)
  99. {
  100. _native.SetMaterial(material, index);
  101. serializableData.materials[index] = material;
  102. }
  103. /// <summary>
  104. /// Layer bitfield that controls whether a renderable is considered visible in a specific camera. Renderable layer
  105. /// must match camera layer in order for the camera to render the component.
  106. /// </summary>
  107. public UInt64 Layers
  108. {
  109. get { return _native.Layers; }
  110. set { _native.Layers = value; serializableData.layers = value; }
  111. }
  112. /// <summary>
  113. /// Gets world bounds of the mesh rendered by this object.
  114. /// </summary>
  115. public Bounds Bounds
  116. {
  117. get { return _native.GetBounds(SceneObject); }
  118. }
  119. private void OnReset()
  120. {
  121. if (_native != null)
  122. _native.OnDestroy();
  123. _native = new NativeRenderable(SceneObject);
  124. // Restore saved values after reset
  125. _native.Mesh = serializableData.mesh;
  126. if (serializableData.materials != null)
  127. _native.Materials = serializableData.materials;
  128. _native.Layers = serializableData.layers;
  129. Animation animation = SceneObject.GetComponent<Animation>();
  130. if (animation != null)
  131. NativeAnimation = animation.Native;
  132. }
  133. private void OnUpdate()
  134. {
  135. _native.UpdateTransform(SceneObject, false);
  136. }
  137. private void OnDestroy()
  138. {
  139. _native.OnDestroy();
  140. }
  141. /// <inheritdoc/>
  142. protected internal override bool CalculateBounds(out AABox box, out Sphere sphere)
  143. {
  144. Bounds bounds = Bounds;
  145. box = bounds.Box;
  146. sphere = bounds.Sphere;
  147. return true;
  148. }
  149. /// <summary>
  150. /// Holds all data the renderable component needs to persist through serialization.
  151. /// </summary>
  152. [SerializeObject]
  153. private class SerializableData
  154. {
  155. public Mesh mesh;
  156. public Material[] materials = new Material[1];
  157. public UInt64 layers = 1;
  158. }
  159. }
  160. /** @} */
  161. }