예제 #1
0
        private static OutlineItem CreateOutlineItem(SceneNode sceneNode)
        {
            var item = new OutlineItem
            {
                Text = $"{sceneNode.GetType().Name} \"{sceneNode.Name}\"",
                Icon = MultiColorGlyphs.SceneNode,
                Children = new OutlineItemCollection(),
                ToolTip = ToolTipSceneNode,
                UserData = sceneNode,
            };

            if (sceneNode is MeshNode)
                item.Icon = MultiColorGlyphs.Mesh;

            if (sceneNode.Children != null)
                foreach (var child in sceneNode.Children)
                    if (child != null)
                        item.Children.Add(CreateOutlineItem(child));

            var mesh = (sceneNode as MeshNode)?.Mesh;
            if (mesh != null)
                item.Children.Add(CreateOutlineItem(mesh));

            return item;
        }
예제 #2
0
        protected virtual void CloneCore(SceneNode source)
        {
            _flags = source._flags;
              Name = source.Name;
              ScaleLocal = source.ScaleLocal;
              PoseLocal = source.PoseLocal;
              LastScaleWorld = source.LastScaleWorld;
              LastPoseWorld = source.LastPoseWorld;
              Shape = source.Shape;     // Shallow copy.
              MaxDistance = source.MaxDistance;
              SortTag = source.SortTag;
              UserData = source.UserData;
              // Do not clone: RenderData, SceneData

              if (source.Children != null)
              {
            if (Children == null)
              Children = new SceneNodeCollection();
            else
              Children.Clear();

            foreach (var child in source.Children)
              Children.Add(child.Clone());
              }
        }
예제 #3
0
    /// <inheritdoc/>
    protected override void CloneCore(SceneNode source)
    {
      base.CloneCore(source);

      var sourceTyped = (ProxyNode)source;
      SetNode((sourceTyped.Node != null) ? sourceTyped.Node.Clone() : null);
      Shape = sourceTyped.Shape.Clone();
    }
예제 #4
0
    // CloneCore() is called to initialize the clone.
    protected override void CloneCore(SceneNode source)
    {
      // Clone the SceneNode properties (base class).
      base.CloneCore(source);

      // Clone the TextNode properties.
      var sourceTextNode = (TextNode)source;
      Color = sourceTextNode.Color;
      Text = sourceTextNode.Text;
    }
예제 #5
0
        /// <summary>
        /// Creates an instance of the <see cref="SceneChangedEventArgs"/> class. (This method reuses a
        /// previously recycled instance or allocates a new instance if necessary.)
        /// </summary>
        /// <param name="sceneNode">The scene node.</param>
        /// <param name="changes">The changes.</param>
        /// <returns>
        /// A new or reusable instance of the <see cref="SceneChangedEventArgs"/> class.
        /// </returns>
        /// <remarks>
        /// <para>
        /// This method tries to obtain a previously recycled instance from a resource pool if resource
        /// pooling is enabled (see <see cref="ResourcePool.Enabled">ResourcePool.Enabled</see>). If no
        /// object is available, a new instance is automatically allocated on the heap.
        /// </para>
        /// <para>
        /// The owner of the object should call <see cref="Recycle"/> when the instance is no longer
        /// needed.
        /// </para>
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="sceneNode"/> is <see langword="null"/>.
        /// </exception>
        public static SceneChangedEventArgs Create(SceneNode sceneNode, SceneChanges changes)
        {
            if (sceneNode == null)
            throw new ArgumentNullException("sceneNode");

              var args = Pool.Obtain();
              args.SceneNode = sceneNode;
              args.Changes = changes;
              return args;
        }
예제 #6
0
 private void AddSubtree(SceneNode node)
 {
   if (node.IsEnabled)
   {
     AddNode(node);
     if (node.Children != null)
       foreach (var childNode in node.Children)
         AddSubtree(childNode);
   }
 }
예제 #7
0
 private void AddNode(SceneNode node)
 {
   var proxyNode = node as ProxyNode;
   if (proxyNode != null)
   {
     if (proxyNode.Node != null)
       AddSubtree(proxyNode.Node);
   }
   else
   {
     SceneNodes.Add(node);
   }
 }
예제 #8
0
        public void Set(SceneNode referenceNode, IList<SceneNode> nodes, RenderContext context)
        {
            Reset();
              ReferenceNode = referenceNode;

              int numberOfNodes = nodes.Count;
              for (int i = 0; i < numberOfNodes; i++)
              {
            var node = nodes[i];
            Debug.Assert(node.ActualIsEnabled, "Scene query contains disabled nodes.");
            SceneNodes.Add(node);
              }
        }
예제 #9
0
        public void Set(SceneNode referenceNode, IList<SceneNode> nodes)
        {
            Reset();
            ReferenceNode = referenceNode;

            for (int i = 0; i < nodes.Count; i++)
            {
                var node = nodes[i];

                if (node.IsRenderable)
                {
                    RenderableNodes.Add(node);
                }
            }
        }
예제 #10
0
    public void Set(SceneNode referenceNode, IList<SceneNode> nodes, RenderContext context)
    {
      Reset();
      ReferenceNode = referenceNode;

      int numberOfNodes = nodes.Count;
      for (int i = 0; i < numberOfNodes; i++)
      {
        var node = nodes[i];
        if ((WboitFlags)node.UserFlags == WboitFlags.Transparent)
          TransparentNodes.Add(node);
        else
          SceneNodes.Add(node);
      }
    }
예제 #11
0
        public void Set(SceneNode referenceNode, IList<SceneNode> nodes, RenderContext context)
        {
            Reset();
              ReferenceNode = referenceNode;

              int numberOfNodes = nodes.Count;
              for (int i = 0; i < numberOfNodes; i++)
              {
            var fogNode = nodes[i] as FogNode;
            if (fogNode != null)
            {
              Debug.Assert(fogNode.ActualIsEnabled, "Scene query contains disabled nodes.");
              FogNodes.Add(fogNode);
            }
              }

              // Sort fog nodes.
              FogNodes.Sort(DescendingFogNodeComparer.Instance);
        }
예제 #12
0
    public void Set(SceneNode referenceNode, IList<SceneNode> nodes, RenderContext context)
    {
      Reset();
      ReferenceNode = referenceNode;

      for (int i = 0; i < nodes.Count; i++)
      {
#if !XBOX360
        if (nodes[i] is TerrainNode)
          TerrainNodes.Add(nodes[i]);
#endif
        if (nodes[i] is CloudLayerNode)
          CloudLayerNodes.Add(nodes[i]);
        else if (nodes[i] is WaterNode)
          WaterNodes.Add(nodes[i]);
        else if (nodes[i] is SceneCaptureNode)
          SceneCaptureNodes.Add(nodes[i]);
        else if (nodes[i] is PlanarReflectionNode)
          PlanarReflectionNodes.Add(nodes[i]);
      }
    }
예제 #13
0
 //--------------------------------------------------------------
 /// <inheritdoc/>
 public override bool CanRender(SceneNode node, RenderContext context)
 {
     return node is PlanarReflectionNode;
 }
예제 #14
0
    // OnLoad() is called when the GameObject is added to the IGameObjectService.
    protected override void OnLoad()
    {
      var particleSystemService = _services.GetInstance<IParticleSystemService>();

      // The campfire consists of two particle systems (fire + smoke) and a light source.
      // 
      //   _campfire (SceneNode)
      //      |
      //      +-- _fireParticles (ParticleSystemNode)
      //      |
      //      +-- _smokeParticles (ParticleSystemNode)
      //      |
      //      +-- _light (LightNode)

      // Use a basic scene node as the root node for the campfire.
      _campfire = new SceneNode
      {
        Name = "Campfire",
        PoseLocal = new Pose(new Vector3F(0, 0, -1)),
        Children = new SceneNodeCollection()
      };

      // Add fire particles.
      var contentManager = _services.GetInstance<ContentManager>();
      var particleSystem = CreateFire(contentManager);
      particleSystemService.ParticleSystems.Add(particleSystem);
      _fireParticles = new ParticleSystemNode(particleSystem)
      {
        // The fire effect lies in the xy plane and shoots into the forward direction (= -z axis).
        // Therefore we rotate the particle system to shoot upwards.
        PoseLocal = new Pose(new Vector3F(0, 0.2f, 0), Matrix33F.CreateRotationX(ConstantsF.PiOver2))
      };
      _campfire.Children.Add(_fireParticles);

      // Add smoke particles.
      particleSystem = CreateSmoke(contentManager);
      particleSystemService.ParticleSystems.Add(particleSystem);
      _smokeParticles = new ParticleSystemNode(particleSystem)
      {
        PoseLocal = new Pose(new Vector3F(0, 0.2f, 0), Matrix33F.CreateRotationX(ConstantsF.PiOver2))
      };
      _campfire.Children.Add(_smokeParticles);

      // Add a point light that illuminates the environment.
      var light = new PointLight
      {
        Attenuation = 0.1f,
        Color = new Vector3F(1, 0.2f, 0),
        HdrScale = 20,
        Range = 4
      };
      _light = new LightNode(light)
      {
        // Optional: We can make this light cast shadows - but this will cost performance!
        //Shadow = new CubeMapShadow { PreferredSize = 64, FilterRadius = 2, JitterResolution = 2048 },
        PoseLocal = new Pose(new Vector3F(0, 1f, 0))
      };
      _campfire.Children.Add(_light);

      // Add campfire to scene.
      var scene = _services.GetInstance<IScene>();
      scene.Children.Add(_campfire);

      // Particle effects can be added multiple times to the scene (= "instancing").
      // Uncomment the following lines to add a few more instance to the scene.
      //for (int i = 0; i < 10; i++)
      //{
      //  var clone = _campfire.Clone();

      //  // Set random scale, position, orientation.
      //  clone.ScaleLocal = _random.NextVector3F(0.5f, 1.5f);
      //  var pose = _campfire.PoseWorld;
      //  pose.Position.X += _random.NextFloat(-10, 10);
      //  pose.Position.Z += _random.NextFloat(-10, 10);
      //  pose.Orientation = Matrix33F.CreateRotationY(_random.NextFloat(-ConstantsF.PiOver2, ConstantsF.PiOver2));
      //  clone.PoseLocal = pose;

      //  scene.Children.Add(clone);
      //}

      // Add GUI controls to the Options window.
      var sampleFramework = _services.GetInstance<SampleFramework>();
      var optionsPanel = sampleFramework.AddOptions("Game Objects");
      var panel = SampleHelper.AddGroupBox(optionsPanel, "CampfireObject");
      SampleHelper.AddCheckBox(
        panel,
        "Enable campfire",
        IsEnabled,
        isChecked => IsEnabled = isChecked);
    }
예제 #15
0
    // OnUnload() is called when the GameObject is removed from the IGameObjectService.
    protected override void OnUnload()
    {
      // Clean up.
      _campfire.Parent.Children.Remove(_campfire);
      _campfire.Dispose(false);
      _campfire = null;

      _fireParticles = null;
      _smokeParticles = null;
      _light = null;
      _random = null;
    }
예제 #16
0
        /// <inheritdoc/>
        protected override void CloneCore(SceneNode source)
        {
            // Clone the SceneNode properties (base class).
              base.CloneCore(source);

              // Clone the TerrainNode properties.
              var sourceTyped = (TerrainNode)source;
              HoleThreshold = sourceTyped.HoleThreshold;
        }
예제 #17
0
        public void Set(SceneNode referenceNode, IList<SceneNode> nodes, RenderContext context)
        {
            ReferenceNode = referenceNode;
              ShadowCasters.Clear();

              // Check if the light is the directional light. If yes, we will check the
              // IsShadowCasterCulled flag.
              var lightNode = referenceNode as LightNode;
              if (lightNode == null)
            lightNode = context.ReferenceNode as LightNode;
              _checkShadowCusterCulling = (lightNode != null) && (lightNode.Light is DirectionalLight);

              int numberOfNodes = nodes.Count;

            #if DEBUG
              for (int i = 0; i < numberOfNodes; i++)
            Debug.Assert(nodes[i].ActualIsEnabled, "Scene query contains disabled nodes.");
            #endif

              if (context.LodCameraNode == null)
              {
            // ----- No LOD
            for (int i = 0; i < numberOfNodes; i++)
            {
              var node = nodes[i];
              if (IsShadowCaster(node))
            ShadowCasters.Add(node);
            }
              }
              else
              {
            // ----- LOD
            // Get values for LOD computations.
            var cameraNode = context.LodCameraNode;
            _cameraPosition = cameraNode.PoseLocal.Position;
            _lodBiasOverYScale = 1 / Math.Abs(cameraNode.Camera.Projection.ToMatrix44F().M11)
                             * cameraNode.LodBias * context.LodBias;

            // Add nodes and evaluate LOD groups.
            for (int i = 0; i < numberOfNodes; i++)
              AddNodeWithLod(nodes[i], context);
              }
        }
예제 #18
0
 // CanRender() checks whether a given scene node can be rendered with this
 // scene node renderer.
 public override bool CanRender(SceneNode node, RenderContext context)
 {
   return node is TextNode;
 }
예제 #19
0
 private void AddSubtree(SceneNode node, RenderContext context)
 {
     if (node.IsEnabled)
       {
     AddNodeWithLod(node, context);
     if (node.Children != null)
       foreach (var childNode in node.Children)
     AddSubtree(childNode, context);
       }
 }
예제 #20
0
    // Sets the node without updating the bounding shape.
    private void SetNode(SceneNode node)
    {
      // Detach proxy.
      if (_node != null)
      {
        SetProxy(_node, null);
        _node.SceneChanged -= OnNodeSceneChanged;
        _node.PoseLocal = Pose.Identity;
        _node.ScaleLocal = Vector3F.One;
      }

      _node = node;

      // Attach proxy.
      if (_node != null)
      {
        SetProxy(_node, this);
        _node.PoseLocal = PoseWorld;
        _node.ScaleLocal = ScaleWorld;
        _node.SceneChanged += OnNodeSceneChanged;
      }
    }
예제 #21
0
    /// <summary>
    /// Sets the <see cref="SceneNode.Proxy"/> in all referenced nodes.
    /// </summary>
    /// <param name="referencedNode">The referenced node.</param>
    /// <param name="proxyNode">The proxy node.</param>
    private static void SetProxy(SceneNode referencedNode, SceneNode proxyNode)
    {
      Debug.Assert(referencedNode != null, "node must not be null.");

      referencedNode.Proxy = proxyNode;
      if (referencedNode.Children != null)
        foreach (var childNode in referencedNode.Children)
          SetProxy(childNode, proxyNode);
    }
예제 #22
0
    //--------------------------------------------------------------
    #region Creation & Cleanup
    //--------------------------------------------------------------

    /// <summary>
    /// Initializes a new instance of the <see cref="ProxyNode"/> class.
    /// </summary>
    /// <param name="node">The scene node.</param>
    public ProxyNode(SceneNode node)
    {
      IsRenderable = true;
      CastsShadows = true;
      Node = node;
    }
예제 #23
0
 /// <summary>
 /// Called when <see cref="Parent"/> was changed.
 /// </summary>
 /// <param name="oldParent">The old parent.</param>
 /// <param name="newParent">The new parent.</param>
 protected virtual void OnParentChanged(SceneNode oldParent, SceneNode newParent)
 {
 }
예제 #24
0
    /// <inheritdoc />
    protected override void CloneCore(SceneNode source)
    {
      // Clone SceneNode properties.
      base.CloneCore(source);

      // Clone FogSphereNode properties.
      var sourceTyped = (FogSphereNode)source;
      Color = sourceTyped.Color;
      Density = sourceTyped.Density;
      BlendMode = sourceTyped.BlendMode;
      Falloff = sourceTyped.Falloff;
      IntersectionSoftness = sourceTyped.IntersectionSoftness;
    }
예제 #25
0
 //--------------------------------------------------------------
 /// <inheritdoc/>
 public void Reset()
 {
     ReferenceNode = null;
       FogNodes.Clear();
 }
예제 #26
0
        /// <inheritdoc/>
        protected override void CloneCore(SceneNode source)
        {
            // Clone SceneNode properties.
              base.CloneCore(source);

              // Clone FigureNode properties.
              var sourceTyped = (FigureNode)source;
              StrokeColor = sourceTyped.StrokeColor;
              StrokeAlpha = sourceTyped.StrokeAlpha;
              StrokeThickness = sourceTyped.StrokeThickness;
              StrokeDashPattern = sourceTyped.StrokeDashPattern;
              DashInWorldSpace = sourceTyped.DashInWorldSpace;
              FillColor = sourceTyped.FillColor;
              FillAlpha = sourceTyped.FillAlpha;
              DrawOrder = sourceTyped.DrawOrder;
        }
예제 #27
0
        private void AddNodeWithLod(SceneNode node, RenderContext context)
        {
            if (!IsShadowCaster(node))
            return;

              bool hasMaxDistance = Numeric.IsPositiveFinite(node.MaxDistance);
              var lodGroupNode = node as LodGroupNode;
              bool isLodGroupNode = (lodGroupNode != null);

              float distance = 0;
              if (hasMaxDistance || isLodGroupNode)
              {
            Debug.Assert(
              node.ScaleWorld.X > 0 && node.ScaleWorld.Y > 0 && node.ScaleWorld.Z > 0,
              "Assuming that all scale factors are positive.");

            // Determine view-normalized distance between scene node and camera node.
            distance = (node.PoseWorld.Position - _cameraPosition).Length;
            distance *= _lodBiasOverYScale;
            distance /= node.ScaleWorld.LargestComponent;
              }

              // Distance Culling: Only handle nodes that are within MaxDistance.
              if (hasMaxDistance && distance >= node.MaxDistance)
            return;   // Ignore scene node.

              if (isLodGroupNode)
              {
            // Evaluate LOD group.
            var lodSelection = lodGroupNode.SelectLod(context, distance);
            AddSubtree(lodSelection.Current, context);
              }
              else
              {
            ShadowCasters.Add(node);
              }
        }
예제 #28
0
        // TODO(matt) - grid creation needs to be able to be customized and should also be to a specific scale
        // TODO(matt) - should also have an intuitive control panel with presets and real time feedback
        // Add a grid with thick major grid lines and thin stroked minor grid lines.
        private void CreateGrid()
        {
            var majorGridLines = new PathFigure2F();
            for (int i = 0; i <= 100; i++)
            {
                majorGridLines.Segments.Add(new LineSegment2F
                {
                    Point1 = new Vector2F(-50, -50 + i),
                    Point2 = new Vector2F(50, -50 + i),
                });
                majorGridLines.Segments.Add(new LineSegment2F
                {
                    Point1 = new Vector2F(-50 + i, -50),
                    Point2 = new Vector2F(-50 + i, 50),
                });
            }

            var minorGridLines = new PathFigure2F();
            for (int i = 0; i < 100; i++)
            {
                minorGridLines.Segments.Add(new LineSegment2F
                {
                    Point1 = new Vector2F(-50, -40.5f + i),
                    Point2 = new Vector2F(50, -40.5f + i),
                });
                minorGridLines.Segments.Add(new LineSegment2F
                {
                    Point1 = new Vector2F(-40.5f + i, -50),
                    Point2 = new Vector2F(-40.5f + i, 50),
                });
            }

            var majorLinesNode = new FigureNode(majorGridLines)
            {
                Name = "Major grid lines",
                PoseLocal = Pose.Identity,
                StrokeThickness = 1,
                StrokeColor = new Vector3F(0.1f),
                StrokeAlpha = 1f,
            };
            var minorLinesNode = new FigureNode(minorGridLines)
            {
                Name = "Minor grid lines",
                PoseLocal = Pose.Identity,
                StrokeThickness = 0.5f,
                StrokeColor = new Vector3F(0.1f),
                StrokeAlpha = 1f,
                //DashInWorldSpace = true,
                //StrokeDashPattern = new Vector4F(10, 4, 0, 0) / 200,
            };
            var gridNode = new SceneNode
            {
                Name = "Grid",
                Children = new SceneNodeCollection(),
                PoseLocal = new Pose(new Vector3F(0, -0.5f, 0)),
            };
            gridNode.Children.Add(majorLinesNode);
            gridNode.Children.Add(minorLinesNode);
            Scene.Children.Add(gridNode);
        } 
예제 #29
0
 private bool IsShadowCaster(SceneNode node)
 {
     if (_checkShadowCusterCulling)
       {
     // Flag CastsShadow must be set.
     // Flag IsShadowCasterCulled must NOT be set.
     return node.GetFlags(SceneNodeFlags.CastsShadows | SceneNodeFlags.IsShadowCasterCulled)
        == SceneNodeFlags.CastsShadows;
       }
       else
       {
     #if !WINDOWS_PHONE && !XBOX360
     return node.GetFlag(SceneNodeFlags.CastsShadows)
        && !(node is TerrainNode);      // Terrain node is only rendered into directional light shadow.
     #else
     return node.GetFlag(SceneNodeFlags.CastsShadows);
     #endif
       }
 }
 //--------------------------------------------------------------
 /// <inheritdoc/>
 public override bool CanRender(SceneNode node, RenderContext context)
 {
     var lightNode = node as LightNode;
       return lightNode != null && lightNode.Shadow is CubeMapShadow;
 }
예제 #31
0
 //--------------------------------------------------------------
 /// <inheritdoc/>
 public override bool CanRender(SceneNode node, RenderContext context)
 {
     return (node is SkyNode) && base.CanRender(node, context);
 }