//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
//**************** Copyright (c) 2016 Marko Pintera (marko.pintera@gmail.com). All rights reserved. **********************//
using System;
using System.Runtime.CompilerServices;
namespace BansheeEngine
{
/** @addtogroup Scene
* @{
*/
///
/// An object in the scene graph. It has a position, place in the hierarchy and optionally a number of attached
/// components.
///
public sealed class SceneObject : GameObject
{
///
/// Name of the scene object.
///
public string Name
{
get { return Internal_GetName(mCachedPtr); }
set { Internal_SetName(mCachedPtr, value); }
}
///
/// Parent in the scene object hierarchy. Null for hierarchy root.
///
public SceneObject Parent
{
get { return Internal_GetParent(mCachedPtr); }
set { Internal_SetParent(mCachedPtr, value); }
}
///
/// Determines if the object's components are being updated or not.
///
public bool Active
{
get { return Internal_GetActive(mCachedPtr); }
set { Internal_SetActive(mCachedPtr, value); }
}
///
/// Sets the mobility of a scene object. This is used primarily as a performance hint to engine systems. Objects
/// with more restricted mobility will result in higher performance. Some mobility constraints will be enforced by
/// the engine itself, while for others the caller must be sure not to break the promise he made when mobility was
/// set. By default scene object's mobility is unrestricted.
///
public ObjectMobility Mobility
{
get { return (ObjectMobility)Internal_GetMobility(mCachedPtr); }
set { Internal_SetMobility(mCachedPtr, (int)value); }
}
///
/// World position. This includes local position of this object, plus position offset of any parents.
///
public Vector3 Position
{
get
{
Vector3 value;
Internal_GetPosition(mCachedPtr, out value);
return value;
}
set
{
Internal_SetPosition(mCachedPtr, ref value);
}
}
///
/// Local space position (relative to the parent).
///
public Vector3 LocalPosition
{
get
{
Vector3 value;
Internal_GetLocalPosition(mCachedPtr, out value);
return value;
}
set
{
Internal_SetLocalPosition(mCachedPtr, ref value);
}
}
///
/// World rotation. This includes local rotation of this object, plus rotation of any parents.
///
public Quaternion Rotation
{
get
{
Quaternion value;
Internal_GetRotation(mCachedPtr, out value);
return value;
}
set
{
Internal_SetRotation(mCachedPtr, ref value);
}
}
///
/// Local rotation (relative to the parent).
///
public Quaternion LocalRotation
{
get
{
Quaternion value;
Internal_GetLocalRotation(mCachedPtr, out value);
return value;
}
set
{
Internal_SetLocalRotation(mCachedPtr, ref value);
}
}
///
/// World space scale. This includes local scale of this object, plus scale of any parent.
///
public Vector3 Scale
{
get
{
Vector3 value;
Internal_GetScale(mCachedPtr, out value);
return value;
}
}
///
/// Local scale (relative to the parent).
///
public Vector3 LocalScale
{
get
{
Vector3 value;
Internal_GetLocalScale(mCachedPtr, out value);
return value;
}
set
{
Internal_SetLocalScale(mCachedPtr, ref value);
}
}
///
/// Returns the world transform matrix. This matrix accounts for position, rotation and scale transformations
/// relative to the world basis.
///
public Matrix4 WorldTransform
{
get
{
Matrix4 value;
Internal_GetWorldTransform(mCachedPtr, out value);
return value;
}
}
///
/// Returns the local transform matrix. This matrix accounts for position, rotation and scale transformations
/// relative to the parent's basis.
///
public Matrix4 LocalTransform
{
get
{
Matrix4 value;
Internal_GetLocalTransform(mCachedPtr, out value);
return value;
}
}
///
/// Direction in world space that points along the local negative Z axis.
///
public Vector3 Forward
{
get
{
Vector3 value;
Internal_GetForward(mCachedPtr, out value);
return value;
}
set
{
Internal_SetForward(mCachedPtr, ref value);
}
}
///
/// Direction in world space that points along the local positive X axis.
///
public Vector3 Right
{
get
{
Vector3 value;
Internal_GetRight(mCachedPtr, out value);
return value;
}
}
///
/// Direction in world space that points along the local positive Y axis.
///
public Vector3 Up
{
get
{
Vector3 value;
Internal_GetUp(mCachedPtr, out value);
return value;
}
}
///
/// Constructor for internal use by the runtime.
///
private SceneObject()
{
}
///
/// Creates a new scene object. Object will initially be parented to scene root and placed at the world origin.
///
/// Name of the scene object.
public SceneObject(string name)
{
Internal_CreateInstance(this, name, 0);
}
///
/// Creates a new scene object. Object will initially be parented to scene root and placed at the world origin.
///
/// Name of the scene object.
/// Specifies this object is for internal use by the runtime. Internal object will not
/// get saved, nor will they be displayed in the editor during non-debug mode.
internal SceneObject(string name, bool isInternal)
{
if(isInternal)
Internal_CreateInstance(this, name, (int)(SceneObjectEditorFlags.DontSave | SceneObjectEditorFlags.Internal | SceneObjectEditorFlags.Persistent));
else
Internal_CreateInstance(this, name, 0);
}
///
/// Constructs a new component of the specified type and adds it to the internal component list.
///
/// Type of component to create.
/// Instance of the new component.
public T AddComponent() where T : Component
{
return (T)Component.Internal_AddComponent(this, typeof (T));
}
///
/// Constructs a new component of the specified type and adds it to the internal component list.
///
/// Type of component to create.
/// Instance of the new component.
public Component AddComponent(Type type)
{
return Component.Internal_AddComponent(this, type);
}
///
/// Searches for a component of a specific type. If there are multiple components matching the type, only the first
/// one found is returned.
///
/// Type of the component to search for. Includes any components derived from the type.
///
/// Component instance if found, null otherwise.
public T GetComponent() where T : Component
{
return (T)Component.Internal_GetComponent(this, typeof(T));
}
///
/// Searches for all components of a specific type.
///
/// Type of the component to search for. Includes any components derived from the type.
///
/// All components matching the specified type.
public T[] GetComponents() where T : Component
{
Component[] components = Component.Internal_GetComponentsPerType(this, typeof (T));
return Array.ConvertAll(components, x => (T) x);
}
///
/// Returns a list of all components attached to this object.
///
/// All components attached to this object.
public Component[] GetComponents()
{
return Component.Internal_GetComponents(this);
}
///
/// Removes a component from the scene object. If there are multiple components matching the type, only the first
/// one found is removed.
///
/// Type of the component to remove. Includes any components derived from the type.
public void RemoveComponent() where T : Component
{
Component.Internal_RemoveComponent(this, typeof(T));
}
///
/// Removes a component from the scene object. If there are multiple components matching the type, only the first
/// one found is removed.
///
/// Type of the component to remove. Includes any components derived from the type.
public void RemoveComponent(Type type)
{
Component.Internal_RemoveComponent(this, type);
}
///
/// Returns the number of child scene objects this object is parent to.
///
/// Number of child scene objects.
public int GetNumChildren()
{
int value;
Internal_GetNumChildren(mCachedPtr, out value);
return value;
}
///
/// Returns a child scene object.
///
/// Index of the child scene object to retrieve.
/// Instance of the child scene object, or null if index is out of range.
public SceneObject GetChild(int idx)
{
return Internal_GetChild(mCachedPtr, idx);
}
///
/// Searches the child objects for an object matching the specified name.
///
/// Name of the object to locate.
/// If true all descendants of the scene object will be searched, otherwise only immediate
/// children.
/// First found scene object, or empty handle if none found.
public SceneObject FindChild(string name, bool recursive = true)
{
return Internal_FindChild(mCachedPtr, name, recursive);
}
///
/// Searches the child objects for objects matching the specified name.
///
/// Name of the objects to locate.
/// If true all descendants of the scene object will be searched, otherwise only immediate
/// children.
/// All scene objects matching the specified name.
public SceneObject[] FindChildren(string name, bool recursive = true)
{
return Internal_FindChildren(mCachedPtr, name, recursive);
}
///
/// Orients the object so it is looking at the provided location.
///
/// Position in local space where to look at.
public void LookAt(Vector3 position)
{
Vector3 up = Vector3.YAxis;
Internal_LookAt(mCachedPtr, ref position, ref up);
}
///
/// Orients the object so it is looking at the provided location.
///
/// Position in world space where to look at.
/// Determines the object's Y axis orientation.
public void LookAt(Vector3 position, Vector3 up)
{
Internal_LookAt(mCachedPtr, ref position, ref up);
}
///
/// Moves the object's position by the vector offset provided along world axes.
///
/// Amount and direction to move the object along.
public void Move(Vector3 amount)
{
Internal_Move(mCachedPtr, ref amount);
}
///
/// Moves the object's position by the vector offset provided along local axes.
///
/// Amount and direction to move the object along.
public void MoveLocal(Vector3 amount)
{
Internal_MoveLocal(mCachedPtr, ref amount);
}
///
/// Rotates the object by the quaternion, in world space.
///
/// Quaternion that specifies the rotation.
public void Rotate(Quaternion amount)
{
Internal_Rotate(mCachedPtr, ref amount);
}
///
/// Rotates around local Z axis.
///
/// Angle to rotate by.
public void Roll(Degree angle)
{
Radian radianAngle = angle;
Internal_Roll(mCachedPtr, ref radianAngle);
}
///
/// Rotates around local Y axis.
///
/// Angle to rotate by.
public void Yaw(Degree angle)
{
Radian radianAngle = angle;
Internal_Yaw(mCachedPtr, ref radianAngle);
}
///
/// Rotates around local X axis.
///
/// Angle to rotate by.
public void Pitch(Degree angle)
{
Radian radianAngle = angle;
Internal_Pitch(mCachedPtr, ref radianAngle);
}
///
/// Destroys the scene object, removing it from scene and stopping component updates.
///
/// If true the scene object will be fully destroyed immediately. This means that objects
/// that are still referencing this scene object might fail. Normally destruction is delayed
/// until the end of the frame to give other objects a chance to stop using it.
public void Destroy(bool immediate = false)
{
Internal_Destroy(mCachedPtr, immediate);
}
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_CreateInstance(SceneObject instance, string name, int flags);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetName(IntPtr nativeInstance, string name);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string Internal_GetName(IntPtr nativeInstance);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetActive(IntPtr nativeInstance, bool value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern bool Internal_GetActive(IntPtr nativeInstance);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetMobility(IntPtr nativeInstance, int value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int Internal_GetMobility(IntPtr nativeInstance);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetParent(IntPtr nativeInstance, SceneObject parent);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern SceneObject Internal_GetParent(IntPtr nativeInstance);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetNumChildren(IntPtr nativeInstance, out int value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern SceneObject Internal_GetChild(IntPtr nativeInstance, int idx);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern SceneObject Internal_FindChild(IntPtr nativeInstance, string name, bool recursive);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern SceneObject[] Internal_FindChildren(IntPtr nativeInstance, string name, bool recursive);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetPosition(IntPtr nativeInstance, out Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetLocalPosition(IntPtr nativeInstance, out Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetRotation(IntPtr nativeInstance, out Quaternion value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetLocalRotation(IntPtr nativeInstance, out Quaternion value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetScale(IntPtr nativeInstance, out Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetLocalScale(IntPtr nativeInstance, out Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetPosition(IntPtr nativeInstance, ref Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetLocalPosition(IntPtr nativeInstance, ref Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetRotation(IntPtr nativeInstance, ref Quaternion value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetLocalRotation(IntPtr nativeInstance, ref Quaternion value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetLocalScale(IntPtr nativeInstance, ref Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetLocalTransform(IntPtr nativeInstance, out Matrix4 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetWorldTransform(IntPtr nativeInstance, out Matrix4 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_LookAt(IntPtr nativeInstance, ref Vector3 direction, ref Vector3 up);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Move(IntPtr nativeInstance, ref Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_MoveLocal(IntPtr nativeInstance, ref Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Rotate(IntPtr nativeInstance, ref Quaternion value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Roll(IntPtr nativeInstance, ref Radian value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Yaw(IntPtr nativeInstance, ref Radian value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Pitch(IntPtr nativeInstance, ref Radian value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_SetForward(IntPtr nativeInstance, ref Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetForward(IntPtr nativeInstance, out Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetUp(IntPtr nativeInstance, out Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_GetRight(IntPtr nativeInstance, out Vector3 value);
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void Internal_Destroy(IntPtr nativeInstance, bool immediate);
}
///
/// Flags that can be used for controlling scene object behaviour.
///
internal enum SceneObjectEditorFlags // Note: Must match C++ enum SceneObjectFlags
{
/// Object wont be in the main scene and its components won't receive updates.
DontInstantiate = 0x01,
/// Object will be skipped when saving the scene hierarchy or a prefab.
DontSave = 0x02,
///
/// Object will remain in the scene even after scene clear, unless destroyed directly. This only works with
/// top-level objects.
///
Persistent = 0x04,
///
/// Provides a hint to external systems that his object is used by engine internals. For example, those systems
/// might not want to display those objects together with the user created ones.
///
Internal = 0x08
}
/** @} */
}