/// <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)); }
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 } }
/// <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; } } } } } }
/// <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(); } }
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 } }