/// <summary>
        /// Recursive render function for drawing normals with a constant size.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="visibleMeshesByNode"></param>
        /// <param name="flags"></param>
        /// <param name="invGlobalScale"></param>
        /// <param name="animated"></param>
        /// <param name="transform"></param>
        private void RecursiveRenderNormals(Node node, Dictionary <Node, List <Mesh> > visibleMeshesByNode, RenderFlags flags,
                                            float invGlobalScale,
                                            bool animated,
                                            Matrix4 transform, int currDispList)
        {
            // TODO unify our use of OpenTK and Assimp matrices
            Matrix4 mConv;

            if (animated)
            {
                Owner.SceneAnimator.GetLocalTransform(node, out mConv);
            }
            else
            {
                Matrix4x4 m = node.Transform;
                mConv = AssimpToOpenTk.FromMatrix(ref m);
            }

            mConv.Transpose();

            // The normal's position and direction are transformed differently, so we manually track the transform.
            transform = mConv * transform;

            if (flags.HasFlag(RenderFlags.ShowNormals))
            {
                List <Mesh> meshList = null;
                if (node.HasMeshes &&
                    (visibleMeshesByNode == null || visibleMeshesByNode.TryGetValue(node, out meshList)))
                {
                    foreach (var index in node.MeshIndices)
                    {
                        var mesh = Owner.Raw.Meshes[index];
                        if (meshList != null && !meshList.Contains(mesh))
                        {
                            continue;
                        }
                        if (currDispList == GetDispList(node.Name))
                        {
                            OverlayNormals.DrawNormals(node, index, mesh, mesh.HasBones && animated ? Skinner : null, invGlobalScale, transform);
                        }
                    }
                }
            }

            for (int i = 0; i < node.ChildCount; i++)
            {
                RecursiveRenderNormals(node.Children[i], visibleMeshesByNode, flags, invGlobalScale, animated, transform, currDispList);
            }
        }
예제 #2
0
        /// <summary>
        /// Recursive render function for drawing opaque geometry with no scaling
        /// in the transformation chain. This is used for overlays, such as drawing
        /// normal vectors or the skeleton.
        /// </summary>
        /// <param name="node"></param>
        /// <param name="visibleMeshesByNode"></param>
        /// <param name="flags"></param>
        /// <param name="invGlobalScale"></param>
        /// <param name="animated"></param>
        private void RecursiveRenderNoScale(Node node, Dictionary <Node, List <Mesh> > visibleMeshesByNode, RenderFlags flags,
                                            float invGlobalScale,
                                            bool animated)
        {
            // TODO unify our use of OpenTK and Assimp matrices
            Matrix4x4 m;
            Matrix4   mConv;

            if (animated)
            {
                Owner.SceneAnimator.GetLocalTransform(node, out mConv);
                OpenTkToAssimp.FromMatrix(ref mConv, out m);
            }
            else
            {
                m = node.Transform;
            }

            // get rid of the scaling part of the matrix
            // TODO this can be done faster and Decompose() doesn't handle
            // non positively semi-definite matrices correctly anyway.

            Vector3D scaling;

            Assimp.Quaternion rotation;
            Vector3D          translation;

            m.Decompose(out scaling, out rotation, out translation);

            rotation.Normalize();

            m     = new Matrix4x4(rotation.GetMatrix()) * Matrix4x4.FromTranslation(translation);
            mConv = AssimpToOpenTk.FromMatrix(ref m);
            mConv.Transpose();

            if (flags.HasFlag(RenderFlags.ShowSkeleton))
            {
                var highlight = false;
                if (visibleMeshesByNode != null)
                {
                    List <Mesh> meshList;
                    if (visibleMeshesByNode.TryGetValue(node, out meshList) && meshList == null)
                    {
                        // If the user hovers over a node in the tab view, all of its descendants
                        // are added to the visible set as well. This is not the intended
                        // behavior for skeleton joints, though! Here we only want to show the
                        // joint corresponding to the node being hovered over.

                        // Therefore, only highlight nodes whose parents either don't exist
                        // or are not in the visible set.
                        if (node.Parent == null || !visibleMeshesByNode.TryGetValue(node.Parent, out meshList) || meshList != null)
                        {
                            highlight = true;
                        }
                    }
                }
                OverlaySkeleton.DrawSkeletonBone(node, invGlobalScale, highlight);
            }

            GL.PushMatrix();
            GL.MultMatrix(ref mConv);

            if (flags.HasFlag(RenderFlags.ShowNormals))
            {
                List <Mesh> meshList = null;
                if (node.HasMeshes &&
                    (visibleMeshesByNode == null || visibleMeshesByNode.TryGetValue(node, out meshList)))
                {
                    foreach (var index in node.MeshIndices)
                    {
                        var mesh = Owner.Raw.Meshes[index];
                        if (meshList != null && !meshList.Contains(mesh))
                        {
                            continue;
                        }

                        OverlayNormals.DrawNormals(node, index, mesh, mesh.HasBones && animated ? Skinner : null, invGlobalScale);
                    }
                }
            }

            for (int i = 0; i < node.ChildCount; i++)
            {
                RecursiveRenderNoScale(node.Children[i], visibleMeshesByNode, flags, invGlobalScale, animated);
            }
            GL.PopMatrix();
        }