using System;
namespace BansheeEngine
{
///
/// Renderable represents any visible object in the scene. It has a mesh, bounds and a set of materials. Renderer will
/// render any Renderable objects visible by a camera.
///
public class Renderable : Component
{
private NativeRenderable _native;
[SerializeField]
private SerializableData serializableData = new SerializableData();
///
/// Returns the non-component version of Renderable that is wrapped by this component.
///
internal NativeRenderable Native
{
get { return _native; }
}
///
/// Mesh to render.
///
public Mesh Mesh
{
get { return _native.Mesh; }
set
{
_native.Mesh = value;
serializableData.mesh = value;
int subMeshCount = 0;
if (value != null)
subMeshCount = value.SubMeshCount;
Material[] newMaterials = new Material[subMeshCount];
int numToCopy = MathEx.Min(newMaterials.Length, serializableData.materials.Length);
Array.Copy(serializableData.materials, newMaterials, numToCopy);
serializableData.materials = newMaterials;
}
}
///
/// Material to use when rendering the mesh. If the mesh contains multiple sub-meshes then you may set individual
/// materials for each sub-mesh.
///
public Material Material
{
get { return _native.GetMaterial(0); }
set
{ _native.SetMaterial(value); serializableData.materials[0] = value; }
}
///
/// Materials to use when rendering the mesh.
///
public Material[] Materials
{
get { return _native.Materials; }
set { _native.Materials = value; }
}
///
/// Returns a material for a specific sub-mesh.
///
/// Index of the sub-mesh.
/// Material used for rendering the sub-mesh at the specified index.
public Material GetMaterial(int index = 0)
{
return _native.GetMaterial(index);
}
///
/// Sets a material for a specific sub-mesh.
///
/// Material to use for rendering the sub-mesh at the specified index.
/// Index of the sub-mesh.
public void SetMaterial(Material material, int index = 0)
{
_native.SetMaterial(material, index);
serializableData.materials[index] = material;
}
///
/// Layer bitfield that controls whether a renderable is considered visible in a specific camera. Renderable layer
/// must match camera layer in order for the camera to render the component.
///
public UInt64 Layers
{
get { return _native.Layers; }
set { _native.Layers = value; serializableData.layers = value; }
}
///
/// Gets world bounds of the mesh rendered by this object.
///
public Bounds Bounds
{
get { return _native.GetBounds(SceneObject); }
}
private void OnInitialize()
{
serializableData.materials = new Material[0];
serializableData.layers = 1;
}
private void OnReset()
{
if (_native != null)
_native.OnDestroy();
_native = new NativeRenderable(SceneObject);
// Restore saved values after reset
_native.Mesh = serializableData.mesh;
if (serializableData.materials != null)
{
for (int i = 0; i < serializableData.materials.Length; i++)
_native.SetMaterial(serializableData.materials[i], i);
}
_native.Layers = serializableData.layers;
}
private void Update()
{
_native.UpdateTransform(SceneObject);
}
private void OnDestroy()
{
_native.OnDestroy();
}
///
/// Holds all data the renderable component needs to persist through serialization.
///
[SerializeObject]
private struct SerializableData
{
public Mesh mesh;
public Material[] materials;
public UInt64 layers;
}
}
}