Esempio n. 1
0
        /// <summary>
        /// Determines whether the opacity of the scene node can be changed using
        /// <see cref="SetInstanceAlpha"/>.
        /// </summary>
        /// <param name="node">The scene node.</param>
        /// <returns>
        /// <see langword="true"/> if the scene node has an alpha parameter that can be changed using
        /// <see cref="SetInstanceAlpha"/>; otherwise, <see langword="false"/>.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="node"/> is <see langword="null"/>.
        /// </exception>
        public static bool SupportsInstanceAlpha(this SceneNode node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            return(node.GetFlag(SceneNodeFlags.HasAlpha));
        }
Esempio n. 2
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
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Sets the opacity (alpha) of a scene node - see remarks.
        /// </summary>
        /// <param name="node">The scene node.</param>
        /// <param name="alpha">The alpha value.</param>
        /// <remarks>
        /// This method can be called for all types of <see cref="SceneNode"/>s. If the node is a
        /// <see cref="MeshNode"/>, the method sets the
        /// <see cref="DefaultEffectParameterSemantics.InstanceAlpha"/> effect parameter bindings in
        /// the material instances. Currently, this method does nothing for all other types of scene
        /// nodes.
        /// </remarks>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="node"/> is <see langword="null"/>.
        /// </exception>
        public static void SetInstanceAlpha(this SceneNode node, float alpha)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            // ReSharper disable CompareOfFloatsByEqualityOperator
            if (alpha == 1)
            {
                // Abort if node's alpha is already equal to 1.
                if (!node.GetFlag(SceneNodeFlags.IsAlphaSet))
                {
                    return;
                }

                // Remember that node's alpha is reset to 1.
                node.ClearFlag(SceneNodeFlags.IsAlphaSet);
            }
            else
            {
                // Remember that node's alpha is not 1.
                node.SetFlag(SceneNodeFlags.IsAlphaSet);
            }
            // ReSharper restore CompareOfFloatsByEqualityOperator

            // The only node which sets the HasAlpha flag is a MeshNode!
            // Cast to MeshNode and update the InstanceAlpha parameter bindings.
            // See also MeshNode.SetHasAlpha().
            var meshNode = node as MeshNode;

            if (meshNode != null)
            {
                foreach (var materialInstance in meshNode.MaterialInstances)
                {
                    foreach (var effectBinding in materialInstance.EffectBindings)
                    {
                        foreach (var parameterBinding in effectBinding.ParameterBindings)
                        {
                            if (ReferenceEquals(parameterBinding.Description.Semantic, DefaultEffectParameterSemantics.InstanceAlpha))
                            {
                                var constParameterBinding = parameterBinding as ConstParameterBinding <float>;
                                if (constParameterBinding != null)
                                {
                                    constParameterBinding.Value = alpha;
                                }

                                break;
                            }
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        /// <inheritdoc/>
        public T Query <T>(SceneNode referenceNode, RenderContext context) where T : class, ISceneQuery, new()
        {
            if (referenceNode == null)
            {
                throw new ArgumentNullException("referenceNode");
            }

            // Use proxy node instead of specified node, if set.
            while (referenceNode.Proxy != null)
            {
                referenceNode = referenceNode.Proxy;
            }

            // Check if the node was modified since Scene.Update(). This can happen, for
            // example, if a CameraNode is rotated to capture 6 sides of a cube map.
            if (referenceNode.GetFlag(SceneNodeFlags.IsDirtyScene))
            {
                // Reset all queries that use this node.
                int numberOfQueries = _queries.Count;
                for (int i = 0; i < numberOfQueries; i++)
                {
                    if (_queries[i].ReferenceNode == referenceNode)
                    {
                        _queries[i].Reset();
                    }
                }

                referenceNode.ClearFlag(SceneNodeFlags.IsDirtyScene);
            }

            try
            {
                // ----- Get query of type T.
                T   query           = null;
                int numberOfQueries = _queries.Count;
                for (int i = 0; i < numberOfQueries; i++)
                {
                    query = _queries[i] as T;
                    if (query != null)
                    {
                        break;
                    }
                }

                if (query != null)
                {
                    // Query exists.
                    // Return cached result if the reference node is the same.
                    if (query.ReferenceNode == referenceNode)
                    {
                        return(query);
                    }
                }
                else
                {
                    // Create new query.
                    query = new T();
                    _queries.Add(query);
                }

                if (referenceNode.Shape is InfiniteShape)
                {
                    // ----- Infinite shape queries.
                    // Return all scene nodes.
                    GetSceneNodes(this, referenceNode, _filter, _tempNodes);
                    query.Set(referenceNode, _tempNodes, context);
                    return(query);
                }

                // Add infinite nodes to temporary list.
                foreach (var node in _infiniteNodes)
                {
                    if (node.ActualIsEnabled && _filter.Filter(new Pair <SceneNode>(referenceNode, node)))
                    {
                        _tempNodes.Add(node);
                    }
                }

                var cameraNode = referenceNode as CameraNode;
                if (cameraNode != null)
                {
                    // ----- Camera frustum queries.
                    // Extract frustum planes.
                    Matrix44F viewProjection = cameraNode.Camera.Projection * cameraNode.View;
                    GeometryHelper.ExtractPlanes(viewProjection, _tempPlanes, false);

                    // Use broad phase to do frustum culling.
                    foreach (var collisionObject in ((DualPartition <CollisionObject>)_collisionDomain.BroadPhase).GetOverlaps(_tempPlanes))
                    {
                        // ISupportFrustumCulling.GetOverlaps() does not apply filtering.
                        // --> Manually check if collision object is enabled.
                        if (collisionObject.Enabled)
                        {
                            //if (collisionObject.GeometricObject.Shape is PlaneShape
                            //    && !HaveAabbPlaneContact(referenceNode, collisionObject))
                            //  continue;

                            var sceneNode = collisionObject.GeometricObject as SceneNode;
                            if (sceneNode != null && _filter.Filter(new Pair <SceneNode>(referenceNode, sceneNode)))
                            {
                                _tempNodes.Add(sceneNode);
                            }
                        }
                    }
                }
                else
                {
                    // ----- Normal object queries.
                    var collisionObject = GetCollisionObject(referenceNode, false);
                    foreach (var contactSet in _collisionDomain.ContactSets.GetContacts(collisionObject))
                    {
                        SceneNode sceneNode;
                        if (contactSet.ObjectA == collisionObject)
                        {
                            sceneNode = contactSet.ObjectB.GeometricObject as SceneNode;
                        }
                        else
                        {
                            sceneNode = contactSet.ObjectA.GeometricObject as SceneNode;
                        }

                        Debug.Assert(sceneNode != null);
                        _tempNodes.Add(sceneNode);
                    }
                }

                query.Set(referenceNode, _tempNodes, context);
                return(query);
            }
            finally
            {
                _tempPlanes.Clear();
                _tempNodes.Clear();
            }
        }
Esempio n. 5
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
       }
 }