Ejemplo n.º 1
0
        /// <summary>
        /// Sorts the provided list by camera space z distance.
        /// Assumes a right-handed coordinate system, so the farthest nodes have the most negative values.</summary>
        /// <param name="list">List of alpha TraverseNodes to sort</param>
        /// <param name="viewMatrix">Current view matrix to transform bounding box centroids by</param>
        public static void SortByCameraSpaceDepth(List <TraverseNode> list, Matrix4F viewMatrix)
        {
            KeyValuePair <float, TraverseNode>[] camSpaceDistances =
                new KeyValuePair <float, TraverseNode> [list.Count];

            for (int i = 0; i < list.Count; ++i)
            {
                TraverseNode node = list[i];
                Vec3F        worldSpaceCentroid = node.WorldSpaceBoundingBox.Centroid;

                Vec3F centerPointInCameraSpace;
                viewMatrix.Transform(worldSpaceCentroid, out centerPointInCameraSpace);

                camSpaceDistances[i] = new KeyValuePair <float, TraverseNode>(centerPointInCameraSpace.Z, node);
            }

            Array.Sort(camSpaceDistances, new CamSpaceDistanceComparer());

            list.Clear();

            foreach (KeyValuePair <float, TraverseNode> entry in camSpaceDistances)
            {
                list.Add(entry.Value);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Traverses the control for rendering</summary>
        /// <param name="graphPath">The path leading to the control</param>
        /// <param name="action">Render action</param>
        /// <param name="list">Traverse list</param>
        public void Traverse(
            Stack <SceneNode> graphPath,
            IRenderAction action,
            ICollection <TraverseNode> list)
        {
            TraverseNode node = action.GetUnusedNode();

            node.Init(action.RenderObject, action.TopMatrix, graphPath, s_renderState);
            list.Add(node);
        }
            public bool TryAdd(TraverseNode node)
            {
                bool passedPositive = (node.RenderState.RenderMode & PassBits) == PassBits;
                bool passedNegative = (node.RenderState.RenderMode & NoPassBits) == 0;

                if (passedPositive && passedNegative)
                {
                    m_nodes.Add(node);
                    m_sorted = false;
                    return(true);
                }
                return(false);
            }
Ejemplo n.º 4
0
        /// <summary>
        /// Performs any traverse actions</summary>
        /// <param name="graphPath">The path leading to the RenderObject</param>
        /// <param name="renderAction">The render action used to dispatch the object</param>
        /// <param name="camera">The Camera used</param>
        /// <param name="traverseList">The traverse list used in the dispatch phase.
        /// RenderObjects participating in the dispatch phase need to push themselves onto the traverse list.</param>
        /// <returns>The TraverseState</returns>
        public virtual TraverseState Traverse(Stack <SceneNode> graphPath, IRenderAction renderAction, Camera camera, ICollection <TraverseNode> traverseList)
        {
            RenderState state = renderAction.RenderState;

            Box boundingBox = null;

            bool alpha = ((state.RenderMode & RenderMode.Alpha) != 0);

            if (alpha)
            {
                boundingBox = GetBoundingBoxObjectSpace();
                boundingBox.Transform(renderAction.TopMatrix);
            }

            if ((state.RenderMode & RenderMode.Smooth) != 0)
            {
                RenderMode origRenderMode = state.RenderMode;
                state.RenderMode &= ~(RenderMode.Wireframe | RenderMode.WireframeColor);

                TraverseNode node = renderAction.GetUnusedNode();
                node.Init(renderAction.RenderObject, renderAction.TopMatrix, graphPath, state);

                if (alpha)
                {
                    node.WorldSpaceBoundingBox = boundingBox;
                }

                traverseList.Add(node);
                state.RenderMode = origRenderMode;
            }

            if ((state.RenderMode & RenderMode.Wireframe) != 0)
            {
                RenderMode origRenderMode = state.RenderMode;
                state.RenderMode &= ~(RenderMode.Smooth | RenderMode.SolidColor |
                                      RenderMode.Textured | RenderMode.Lit);

                TraverseNode node = renderAction.GetUnusedNode();
                node.Init(renderAction.RenderObject, renderAction.TopMatrix, graphPath, state);

                if (alpha)
                {
                    node.WorldSpaceBoundingBox = boundingBox;
                }

                traverseList.Add(node);
                state.RenderMode = origRenderMode;
            }

            return(renderAction.TraverseState);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Returns either a new or previously used TraverseNode for use by IRenderObject's
        /// Traverse(). The caller must place this node on the traverse list and not maintain
        /// a permanent reference to it.</summary>
        /// <returns>Either a new or previously used TraverseNode</returns>
        public TraverseNode GetUnusedNode()
        {
            TraverseNode node;

            if (m_nextUnusedNode < m_nodePool.Count)
            {
                node = m_nodePool[m_nextUnusedNode];
            }
            else
            {
                node = new TraverseNode();
                m_nodePool.Add(node);
            }
            m_nextUnusedNode++;

            return(node);
        }
Ejemplo n.º 6
0
        private HitRecord[] PopulateOpenGlSelection(ICollection<TraverseNode> traverseList)
        {
            // Ensure that OpenGL is in correct state.
            double[] viewMat = null;
            double[] projectionMat = null;
            int[] viewport = null;
            if (m_frustumPick == false)
            {
                Gl.glViewport(0, 0, m_width, m_height);
                Gl.glMatrixMode(Gl.GL_PROJECTION);
                Gl.glLoadIdentity();
                Util3D.glMultMatrixf(m_projectionMatrix);

                Gl.glMatrixMode(Gl.GL_MODELVIEW);
                Gl.glLoadIdentity();
                Util3D.glMultMatrixf(m_viewMatrix);

                viewMat = new double[16];
                Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX, viewMat);

                projectionMat = new double[16];
                Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX, projectionMat);

                viewport = new int[4];
                viewport[0] = viewport[1] = 0;
                viewport[2] = m_width;
                viewport[3] = m_height;
            }

            // Construct traverse array
            HitRecord[] selection = null;
            List<HitRecord> selectionList = new List<HitRecord>();
            TraverseNode[] travArray = new TraverseNode[traverseList.Count];
            traverseList.CopyTo(travArray, 0);

            uint start = 0;
            for (int i = 0; i < m_openGlHits; ++i)
            {
                uint nameCount = (uint)m_selectionBuffer[start];

                if (nameCount > 0)
                {
                    uint travNodeIndex = (uint)m_selectionBuffer[start + 3];
                    TraverseNode travNode = travArray[travNodeIndex];
                    HitRecord hitRecord;
                    if (m_frustumPick)
                    {
                        hitRecord = new HitRecord(
                            travNode.GraphPath,
                            travNode.RenderObject,
                            new Matrix4F(travNode.Transform),
                            new uint[nameCount - 1]);
                    }
                    else
                    {
                        hitRecord = new HitRecord(
                            travNode.GraphPath,
                            travNode.RenderObject,
                            new Matrix4F(travNode.Transform),
                            new uint[nameCount - 1]);

                        // Transform screen to world and record world-space intersection point.
                        float zMin = ((float)((uint)m_selectionBuffer[start + 1])) / 0xFFFFFFFF;
                        Vec3F intersectionPt = GetWorldIntersectionFromScreen(
                            m_x, m_y, zMin,
                            viewMat, projectionMat, viewport);
                        hitRecord.WorldIntersection = intersectionPt;
                    }

                    // Populate object data
                    for (uint j = 0; j < nameCount - 1; j++)
                    {
                        hitRecord.RenderObjectData[j] = (uint)m_selectionBuffer[start + 4 + j];
                    }

                    selectionList.Add(hitRecord);

                    start += 3 + nameCount;
                }
            }
            selection = new HitRecord[selectionList.Count];
            selectionList.CopyTo(selection, 0);
            return selection;
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Returns either a new or previously used TraverseNode for use by IRenderObject's
        /// Traverse(). The caller must place this node on the traverse list and not maintain
        /// a permanent reference to it.</summary>
        /// <returns>Either a new or previously used TraverseNode</returns>
        public TraverseNode GetUnusedNode()
        {
            TraverseNode node;
            if (m_nextUnusedNode < m_nodePool.Count)
            {
                node = m_nodePool[m_nextUnusedNode];
            }
            else
            {
                node = new TraverseNode();
                m_nodePool.Add(node);
            }
            m_nextUnusedNode++;

            return node;
        }
Ejemplo n.º 8
0
        private HitRecord[] PopulateOpenGlSelection(ICollection <TraverseNode> traverseList)
        {
            // Ensure that OpenGL is in correct state.
            double[] viewMat       = null;
            double[] projectionMat = null;
            int[]    viewport      = null;
            if (m_frustumPick == false)
            {
                Gl.glViewport(0, 0, m_width, m_height);
                Gl.glMatrixMode(Gl.GL_PROJECTION);
                Gl.glLoadIdentity();
                Util3D.glMultMatrixf(m_projectionMatrix);

                Gl.glMatrixMode(Gl.GL_MODELVIEW);
                Gl.glLoadIdentity();
                Util3D.glMultMatrixf(m_viewMatrix);

                viewMat = new double[16];
                Gl.glGetDoublev(Gl.GL_MODELVIEW_MATRIX, viewMat);

                projectionMat = new double[16];
                Gl.glGetDoublev(Gl.GL_PROJECTION_MATRIX, projectionMat);

                viewport    = new int[4];
                viewport[0] = viewport[1] = 0;
                viewport[2] = m_width;
                viewport[3] = m_height;
            }

            // Construct traverse array
            HitRecord[]      selection     = null;
            List <HitRecord> selectionList = new List <HitRecord>();

            TraverseNode[] travArray = new TraverseNode[traverseList.Count];
            traverseList.CopyTo(travArray, 0);

            uint start = 0;

            for (int i = 0; i < m_openGlHits; ++i)
            {
                uint nameCount = (uint)m_selectionBuffer[start];

                if (nameCount > 0)
                {
                    uint         travNodeIndex = (uint)m_selectionBuffer[start + 3];
                    TraverseNode travNode      = travArray[travNodeIndex];
                    HitRecord    hitRecord;
                    if (m_frustumPick)
                    {
                        hitRecord = new HitRecord(
                            travNode.GraphPath,
                            travNode.RenderObject,
                            new Matrix4F(travNode.Transform),
                            new uint[nameCount - 1]);
                    }
                    else
                    {
                        hitRecord = new HitRecord(
                            travNode.GraphPath,
                            travNode.RenderObject,
                            new Matrix4F(travNode.Transform),
                            new uint[nameCount - 1]);

                        // Transform screen to world and record world-space intersection point.
                        float zMin           = ((float)((uint)m_selectionBuffer[start + 1])) / 0xFFFFFFFF;
                        Vec3F intersectionPt = GetWorldIntersectionFromScreen(
                            m_x, m_y, zMin,
                            viewMat, projectionMat, viewport);
                        hitRecord.WorldIntersection = intersectionPt;
                    }

                    // Populate object data
                    for (uint j = 0; j < nameCount - 1; j++)
                    {
                        hitRecord.RenderObjectData[j] = (uint)m_selectionBuffer[start + 4 + j];
                    }

                    selectionList.Add(hitRecord);

                    start += 3 + nameCount;
                }
            }
            selection = new HitRecord[selectionList.Count];
            selectionList.CopyTo(selection, 0);
            return(selection);
        }