AxiomSceneNode.cs :  » Game » RealmForge » RealmForge » SceneObjects » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » RealmForge 
RealmForge » RealmForge » SceneObjects » AxiomSceneNode.cs
using System;
using System.Collections;
using System.Collections.Specialized;
using RealmForge.Rendering;
using AxAxiom.Core;
using Axiom.MathLib;
using Axiom.Core;
using Axiom.Controllers;
using Axiom.Controllers.Canned;
using RealmForge;
using RealmForge.Physics;
using RealmForge.Scripting;
using MathUtilAxiom.MathLib.MathUtil;
using RealmForge.Scene;
using Axiom.Animating;
using RealmForge.Animation;

namespace RealmForge.SceneObjects{
  /// <summary>
  /// Scene Node for the Axiom Engine
  /// </summary>
  public class AxiomSceneNode : SceneNode  {
    #region Fields
    protected Ax.SceneNode node = null;
    protected ISceneNode trackTarget = null;
    protected bool tracking = false;
    protected Vector3 positionBeforeHidingParents;

    #endregion

    #region Constructors
    public AxiomSceneNode(string id) : this(id, AxiomSceneManager.AxiomInstance) {
    }
    protected internal AxiomSceneNode(string id, Ax.SceneManager scene) : this(id, scene, false){
    }
    /// <summary>
    /// Creates an instance of AxiomSceneNode
    /// </summary>
    /// <remarks>
    /// This constructor would be internal but it needs to be used by custom scene objects that derive from it in plugins 
    /// and it cant be protected as it needs to be used by the SceneBuilder though we may want to consider it if the SceneBuilder was to use
    /// the simple id only constructor
    /// </remarks>
    /// <param name="scene"></param>
    /// <param name="id"></param>
    /// <param name="qualifyMovementNodeID">this should be true for classes that inherit from this one and us the unique ID for their own entity for instance</param>
    protected internal AxiomSceneNode(string id, Ax.SceneManager scene, bool qualifyMovementNodeID )  : base(id){
      if(qualifyMovementNodeID)  //##{id}_MovementNode is the format used for nodes used under the hood
        node = scene.CreateSceneNode( RF.Scene.GetInternalID(id, "MovementNode") );
      else
        node = scene.CreateSceneNode(id);
    }
    #endregion

    #region Methods

    #region Protected


    protected override void InternalAddChild(ISceneNode newChild) {
      object obj = newChild.UnderlyingObject;
      if(obj is Ax.Node) {
        Ax.Node n = (Ax.Node)obj;

        //HACK: This should be done by Axiom
        if(n.Parent != null)
          n.Parent.RemoveChild(n);

        node.AddChild((Ax.Node)obj);
      }
      else{
        Ax.SceneNode movementNode = ((AxiomSceneNode)newChild).node;

        //HACK: This should be handled by Axiom, setting ParentNode to null wont remove from the parents collection
        if(movementNode != null && movementNode.Parent != null)
          movementNode.Parent.RemoveChild(movementNode);

        this.node.AddChild(movementNode);
      }
    }

    protected override void InternalRemoveChild(ISceneNode child) {
      if(child == null)
        Errors.ArgumentNull("Child can not be null");
      object obj = child.UnderlyingObject;
      if(obj is Ax.Node) {
        node.RemoveChild((Ax.Node)obj);
      }
      else{
        Ax.Node childNode = ((Ax.SceneObject)obj).ParentNode;
        node.RemoveChild(childNode.Name);
      }
      
    }

    #endregion

    #region Create Functions

    public ScriptEvent CreateTimeFunctionEvent(string eventName, Script eventHandler, float fireRate, IControllerFunction function) {
      ScriptEvent scriptEvent = this.Events.CreateEventIfNeeded(eventName);
      if(eventHandler != null)
        scriptEvent.AddHandler(eventHandler);
      EventTrigger trigger = new TimeFunctionEventTrigger(eventName,fireRate,function);
      AddEventTrigger(trigger);
      return scriptEvent;
    }

    public ScriptEvent CreateTimeFunctionEvent(string eventName, Script eventHandler, float fireRate, WaveformType type, float baseVal, float frequency, float phase, float amplitude, bool useDelta) {
      WaveformControllerFunction function = new WaveformControllerFunction(type, baseVal, frequency, phase, amplitude, useDelta);
      return CreateTimeFunctionEvent(eventName, eventHandler, fireRate, function);
    }

    public ScriptEvent CreateTimeFunctionEvent(string eventName, Script eventHandler, float fireRate, WaveformType type, float baseVal, float frequency, float phase, float amplitude) {
      return CreateTimeFunctionEvent(eventName, eventHandler, fireRate,
        type, baseVal, frequency, phase, amplitude, true);
    }

    public ScriptEvent CreateTimeFunctionEvent(string eventName, Script eventHandler, float fireRate, WaveformType type, float baseVal, float frequency, float phase) {
      return CreateTimeFunctionEvent(eventName, eventHandler, fireRate,
        type, baseVal, frequency, phase, 1f);
    }

    public ScriptEvent CreateTimeFunctionEvent(string eventName, Script eventHandler, float fireRate, WaveformType type, float baseVal, float frequency) {
      return CreateTimeFunctionEvent(eventName, eventHandler, fireRate,
        type, baseVal, frequency, 0f);
    }

    public ScriptEvent CreateTimeFunctionEvent(string eventName, Script eventHandler, float fireRate, WaveformType type, float baseVal) {
      return CreateTimeFunctionEvent(eventName, eventHandler, fireRate,
        type, baseVal, 1f);
    }

    public ScriptEvent CreateTimeFunctionEvent(string eventName, Script eventHandler, float fireRate, WaveformType type) {
      return CreateTimeFunctionEvent(eventName, eventHandler, fireRate,
        type, 0f);
    }

    public ScriptEvent CreateTimeFunctionEvent(string eventName, Script eventHandler, float fireRate) {
      return CreateTimeFunctionEvent(eventName, eventHandler, fireRate,
        WaveformType.Sine);
    }

    #endregion

    #region Public

    public override void ShowOnlyThis() 
    {
      
      if(parent == null)
        return;
      foreach(ISceneNode node in parent.Children) {
        if(node != this)
          node.Visible = false;
      }

      /*
      if(node.Parent != null)
      node.Position += off = node.Parent.DerivedPosition;
      AxiomSceneManager.AxiomInstance.OverrideRootSceneNode(node);
      */
    }

    public override void StopShowingOnlyThis() 
    {
      if(parent == null)
        return;
      foreach(ISceneNode node in parent.Children) {
          node.Visible = true;
      }
      /*
      node.Position -= off;
      AxiomSceneManager.AxiomInstance.RestoreRootSceneNode();
      */
    }
    

    public override IAnimation CreateAnimation(string animationName, float timeLength, bool splineInterpolation, bool keyFramesArePositions, params Vector3[] keyFrames) {
      Ax.SceneManager scene = AxiomSceneManager.AxiomInstance;
      //qualify the name because this animation is only for this node but the name must be globally unique
      animationName = ID + '.' + animationName;  //qualify
      Axiom.Animating.Animation anim = scene.CreateAnimation(animationName, timeLength);
      AnimationTrack track = anim.CreateTrack(0, this.node);
      //spline is the default for Axion animations
      anim.InterpolationMode = (splineInterpolation? InterpolationMode.Spline: InterpolationMode.Linear);
      int keyFrameCount = keyFrames.Length;  //get the number of key frames to create (one for each translation/movement vector)
      if(keyFrameCount == 1)
        Errors.Argument("There must be either no keyFrameMovements or more then one");
      else if(keyFrameCount != 0) {
        float timePerKeyFrame = timeLength / (keyFrameCount - 1);  //the time between each frame with one frame at the start and another at the end
        Vector3 lastPosition = Vector3.Zero;
        for(int i = 0; i<keyFrameCount; i++) {
          KeyFrame frame = track.CreateKeyFrame(timePerKeyFrame * i);
          
          if(keyFramesArePositions && i > 0) {
            frame.Translate = keyFrames[i] - keyFrames[i-1];//target pos - current = offset to get there
          } else
            frame.Translate = keyFrames[i];
        }
      }
      return new RealmForge.Animation.AxiomAnimation(this, scene.CreateAnimationState(animationName));

    }

    public override void LookAt(Vector3 targetAbsolutePosition) {
      //world will error if there is no parent node
      node.LookAt(targetAbsolutePosition,(parent == null || !this.isShown)? TransformSpace.Local: TransformSpace.World);
      if(physBody != null)
        this.physBody.Orientation = node.DerivedOrientation;
    }

    #endregion

    #endregion

    #region Properties

    public Ax.SceneNode MovementNode { get { return this.node; } }

    public override bool ShowBoundingBox {
      get{ return node.ShowBoundingBox; }
      set{ node.ShowBoundingBox = value; }
    }

    /// <summary>
    /// Gets or Sets the offset for tracking a target
    /// </summary>
    public override Vector3 TrackingOffset {
      get {
        return node.AutoTrackOffset;
      }
      set{
        node.AutoTrackOffset = value;
      }
    }
    
    

    /// <summary>
    /// Gets or Sets the target node that is being tracked
    /// </summary>
    public override ISceneNode TrackingTarget {
      get { return trackTarget; }
      set{
        trackTarget = value;
        if(tracking)  //if not disabled
          node.AutoTrackTarget = (Ax.SceneNode)trackTarget.UnderlyingNode;  //set the target movement node
        
      }
    }

    
    public override string TrackingTargetID 
    {
      get{ return (trackTarget == null)? null: trackTarget.ID; }
      set
      {
        trackTarget = RF.Scene.GetSceneNode(value);
      }
    }

    /// <summary>
    /// Gets or Sets if this camera is tracking a target
    /// </summary>
    public override bool Tracking {
      get {
        //use this flag so that Tracking can be set before TrackingTarget yet have this still work
        return tracking; //node.AutoTrackTarget != null;
      } 
      set{
        tracking = value;
        if(tracking && trackTarget != null)
          node.AutoTrackTarget = (Ax.SceneNode)trackTarget.UnderlyingNode;
        else
          node.AutoTrackTarget = null;
      }
    }
    public override object UnderlyingNode { get{ return node; } }

    public override object UnderlyingObject {
      get { return node; }
      set {
        node = (Ax.SceneNode)value;
      }
    }
    /// <summary>
    /// Gets the axis-alingned bounding box in absolute coordinates that encompasses this node and all of its children
    /// </summary>
    public override AxisAlignedBox CombinedBoundingBox { get { return node.WorldAABB; }   }
    
    
    /// <summary>
    /// Gets the bound sphere in absolute coordinates that encompasses this node and all of its children
    /// </summary>
    public override Sphere CombinedBoundingSphere { get { return node.WorldBoundingSphere; } }

    
    /// <summary>
    /// Gets the radius of the bounding sphere that encompasses this node and all of its children
    /// </summary>
    public override float CombinedBoundingRadius { get { return node.WorldBoundingSphere.Radius; } }
    

    /// <summary>
    /// 
    /// </summary>
    /// <remarks>Scale is in relative to the nodes origon similiar to orientation</remarks>
    public override Vector3 Scale { get { return node.ScaleFactor; } set { node.ScaleFactor = value; } }

    
    /// <summary>
    /// 
    /// </summary>
    /// <remarks>Scale is in relative to the nodes origon similiar to orientation</remarks>
    public override Vector3 AbsoluteScale {
      get{ return node.DerivedScale; }
      set{ node.ScaleFactor = value - node.DerivedScale; }
    }

    /// <summary>
    /// If children will be scaled with this node
    /// </summary>
    /// <remarks>By default children are scaled with this parents
    /// You may want to disable this for example to prevent trees being scaled with a landmass or weapons with a characters height
    /// This is applied retroactivly for all newly added children</remarks>
    public override bool InheritScale {
      get{ return node.InheritScale; }
      set{ node.InheritScale = value; }
    }

    
    /// <summary>
    /// Gets or Sets the Orientation or direction faced relative to the parent node
    /// </summary>
    /// <remarks>Triggers the OrientationChanged event if the value is different from the current one</remarks>
    public override Quaternion Orientation {
      get { return node.Orientation; }
      set {
        Quaternion oldOri = node.Orientation;
        if(oldOri == value)
          return;
        node.Orientation = value;
        
        OrientationChanged.Trigger(oldOri);
      }
    }

    /// <summary>
    /// Gets or Sets the absolute Orientation or direction faced relative to the world as derived from all its parent nodes
    /// </summary>
    /// <remarks>Triggers the OrientationChanged event if the value is different from the current one</remarks>
    public override Quaternion AbsoluteOrientation {
      get { return node.DerivedOrientation; }
      set{
        Ax.Node parentMovementNode = node.Parent;
        //Orientation *= value / node.DerivedOrientation
        //orientation is rotated by the difference between the current and the target orientation
        if(parentMovementNode == null)
          Orientation = value;
        else {
          Orientation = value * parentMovementNode.DerivedOrientation.Inverse();
        }
      }
    }
  

    /// <summary>
    /// Gets or Sets the Position of this node or the offset relative to the parent node
    /// </summary>
    /// <remarks>Triggers the PositionChanged event if the value is different from the current one</remarks>
    public override Vector3 Position {
      get { return node.Position; }
      set {
        Vector3 oldPos = node.Position;
        if(oldPos != value) {
          node.Position = value;
          PositionChanged.Trigger(oldPos);
        }
      }  
    }

    /// <summary>
    /// Gets or Sets the absolute position of this node relative to the world as derived from all its parents relative
    /// </summary>
    /// <remarks>Triggers the PositionChanged event if the value is different from the current one</remarks>
    public override Vector3 AbsolutePosition {
      get {
        return node.DerivedPosition;
      }
      set {
        Position = value - node.DerivedPosition;
      }
    }


    public override string ID {
      get{ return node.Name; }
      set{
        string old = ID;
        if(value != old) 
        {
          if(parent != null) 
          {//re-key in both axiom and realmforge's child collections
            ((AxiomSceneNode)parent).RekeyChild(old, value);
          }
          
          node.Name = value;
          SceneNodeRenamedArgs args = new SceneNodeRenamedArgs(this, old, value);
          this.Renamed.Trigger(args);
          RF.Scene.SceneObjectRenamed.Trigger(args);
        }
      }
    }
    #endregion
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.