/// /// This file is part of ILNumerics Community Edition. /// /// ILNumerics Community Edition - high performance computing for applications. /// Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net /// /// ILNumerics Community Edition is free software: you can redistribute it and/or modify /// it under the terms of the GNU General Public License version 3 as published by /// the Free Software Foundation. /// /// ILNumerics Community Edition is distributed in the hope that it will be useful, /// but WITHOUT ANY WARRANTY; without even the implied warranty of /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /// GNU General Public License for more details. /// /// You should have received a copy of the GNU General Public License /// along with ILNumerics Community Edition. See the file License.txt in the root /// of your distribution package. If not, see . /// /// In addition this software uses the following components and/or licenses: /// /// ================================================================================= /// The Open Toolkit Library License /// /// Copyright (c) 2006 - 2009 the Open Toolkit library. /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal /// in the Software without restriction, including without limitation the rights to /// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of /// the Software, and to permit persons to whom the Software is furnished to do /// so, subject to the following conditions: /// /// The above copyright notice and this permission notice shall be included in all /// copies or substantial portions of the Software. /// /// ================================================================================= /// using System; using System.Collections.Generic; using System.Text; using ILNumerics.Drawing; using ILNumerics.Drawing.Shapes; namespace ILNumerics.Drawing.Graphs { /// /// scene graph inner node, collection of children /// public class ILSceneGraphInnerNode : ILSceneGraphNode, ICollection, IList { #region attributes private List m_childs; private ILArray m_centers; #endregion #region constructors public ILSceneGraphInnerNode(ILPanel panel) :base (panel) { m_centers = ILMath.returnType(); m_childs = new List(); } #endregion #region public interface /// /// recompute the size spanned by this node, may fires Changed() event /// internal override void Configure() { if (m_invalidated) { // configure childs (compute limits) first foreach (ILSceneGraphNode child in m_childs) { child.Configure(); } bool sizechanged = false; ILPoint3Df oldMin = m_positionMin; ILPoint3Df oldMax = m_positionMax; ComputeNodeLimits(); if (oldMin != m_positionMin) sizechanged = true; if (oldMax != m_positionMax) sizechanged = true; m_invalidated = false; if (sizechanged) OnSizeChanged(); } } internal override void Draw(ILRenderProperties props) { if (!m_visible) { return; } if (m_childs != null && m_childs.Count > 0) { ILArray indices = Computation.GetSortedIndices( m_centers, m_panel.Camera.Position); foreach (int i in indices) { if (m_childs[i].Visible) m_childs[i].Draw(props); } } } public override void Invalidate() { base.Invalidate(); m_centers.a = ILMath.empty(ILSize.Empty00); } /// /// compute limits of the cube tightly enclosing the branch below this node /// /// protected override void ComputeNodeLimits() { if (m_childs == null || m_childs.Count == 0) { m_positionMin = ILPoint3Df.Empty; m_positionMax = ILPoint3Df.Empty; return; } // acquire maximum position ILPoint3Df curMax = ILPoint3Df.MinValue; ILPoint3Df curMin = ILPoint3Df.MaxValue; foreach (ILSceneGraphNode node in m_childs) { curMin = ILPoint3Df.Min(node.PositionMin, curMin); } curMax = ILPoint3Df.MinValue; foreach (ILSceneGraphNode node in m_childs) { curMax = ILPoint3Df.Max(node.PositionMax, curMax); } m_positionMax = curMax; m_positionMin = curMin; m_center = (m_positionMax + m_positionMin) / 2; // stores childs centers for sorting if (m_centers.IsEmpty) m_centers.a = ILMath.zeros(m_childs.Count, 3); for (int i = m_childs.Count; i-- > 0; ) { ILPoint3Df center = m_childs[i].Center; m_centers.SetValue(center.X, i, 0); m_centers.SetValue(center.Y, i, 1); m_centers.SetValue(center.Z, i, 2); } } internal override void CollectAllChildren(List nodes) { nodes.Add(this); // base.CollectAllChildren(nodes); // add self if (m_childs != null) { foreach (ILSceneGraphNode child in m_childs) { child.CollectAllChildren(nodes); } } } public virtual void Add(ILShape shape) { ILSceneGraphShapedLeaf node = new ILSceneGraphShapedLeaf(m_panel); node.Parent = this; node.Shape = shape; m_childs.Add(node); Invalidate(); OnNodeAdded(node); } public virtual void Remove(ILShape shape) { ILSceneGraphNode node = null; foreach (ILSceneGraphNode n in m_childs) { if (n is ILSceneGraphShapedLeaf) { if (object.Equals((n as ILSceneGraphShapedLeaf).Shape,shape)) { node = n; break; } } } if (node != null) { m_childs.Remove(node); OnNodeRemoved(node); } } #endregion #region IList Member public virtual ILSceneGraphNode this[int i] { get { return m_childs[i]; } set { m_childs[i] = value; Invalidate(); } } public virtual int IndexOf(ILSceneGraphNode item) { return m_childs.IndexOf(item); } public virtual void Insert(int index, ILSceneGraphNode item) { m_childs.Insert(index, item); Invalidate(); } public virtual void RemoveAt(int index) { m_childs.RemoveAt(index); Invalidate(); } #endregion #region ICollection Member /// /// add a single node to the end of child collection /// /// node to add public virtual void Add(ILSceneGraphNode item) { m_childs.Add(item); item.Parent = this; item.Invalidate(); OnNodeAdded(item); } /// /// wipe all nodes from the collection /// public virtual void Clear() { m_childs.Clear(); Invalidate(); } /// /// Determine, if this collection contains a specific node item /// /// /// public bool Contains(ILSceneGraphNode item) { return m_childs.Contains(item); } public void CopyTo(ILSceneGraphNode[] array, int arrayIndex) { m_childs.CopyTo(array, arrayIndex); } /// /// Number of children contained in this node /// public virtual int Count { get { return m_childs.Count; } } /// /// determine if this collection is readonly, (returns 'false') /// public bool IsReadOnly { get { return false; } } /// /// remove a single child node from the collection /// /// node to be removed /// true public virtual bool Remove(ILSceneGraphNode item) { m_childs.Remove(item); Invalidate(); return true; } #endregion #region private helpers private class Computation : ILNumerics.ILMath { /// /// compute distance to camera and return sorted indices for rendering /// /// current primitive centers /// current camera position /// sorted indices of primitives in descending order internal static ILRetArray GetSortedIndices(ILInArray centers, ILPoint3Df position) { using (ILScope.Enter(centers)) { ILArray pos = array(size(1,3), -position.X, -position.Y, -position.Z); // move camera outside of centers pos.a *= maxall(abs(centers)); //pos.a = repmat(pos, centers.Dimensions[0], 1); // compute distances ILArray dist = sum(pow(centers - pos, 2), 1); ILArray ret = empty(); sort(dist, ret, 0, false); return toint32(ret); } } } #endregion } }