Esempio n. 1
0
        /// <summary>
        /// Helper for ComputeBoundingBox(out Vector3 sceneMin, out Vector3 sceneMax)
        /// </summary>
        /// <param name="node"></param>
        /// <param name="min"></param>
        /// <param name="max"></param>
        /// <param name="trafo"></param>
        private void ComputeBoundingBox(Node node, ref Vector3 min, ref Vector3 max, ref Matrix4 trafo)
        {
            if (node.HasMeshes)
            {
                foreach (var mesh in node.MeshIndices.Select(index => _raw.Meshes[index]))
                {
                    for (var i = 0; i < mesh.VertexCount; i++)
                    {
                        var tmp = AssimpToOpenTk.FromVector(mesh.Vertices[i]);
                        Vector3.Transform(ref tmp, ref trafo, out tmp);

                        min.X = Math.Min(min.X, tmp.X);
                        min.Y = Math.Min(min.Y, tmp.Y);
                        min.Z = Math.Min(min.Z, tmp.Z);

                        max.X = Math.Max(max.X, tmp.X);
                        max.Y = Math.Max(max.Y, tmp.Y);
                        max.Z = Math.Max(max.Z, tmp.Z);
                    }
                }
            }

            for (var i = 0; i < node.ChildCount; i++)
            {
                var prev = trafo;
                var mat  = AssimpToOpenTk.FromMatrix(node.Children[i].Transform);
                mat.Transpose();
                Matrix4.Mult(ref mat, ref prev, out prev);

                ComputeBoundingBox(node.Children[i], ref min, ref max, ref prev);
            }
        }
Esempio n. 2
0
        public static void DrawNormals(Node node, int meshIndex, Mesh mesh, CpuSkinningEvaluator skinner, float invGlobalScale, Matrix4 transform)
        {
            if (!mesh.HasNormals)
            {
                return;
            }

            // The normal directions are transformed using the transpose(inverse(transform)).
            // This ensures correct direction is used when non-uniform scaling is present.
            Matrix4 normalMatrix = transform;

            normalMatrix.Invert();
            normalMatrix.Transpose();

            // Scale by scene size because the scene will be resized to fit
            // the unit box, but the normals should have a fixed length.
            var scale = invGlobalScale * 0.05f;

            GL.Begin(BeginMode.Lines);

            GL.Disable(EnableCap.Lighting);
            GL.Disable(EnableCap.Texture2D);
            GL.Enable(EnableCap.ColorMaterial);

            GL.Color4(new Color4(0.0f, 1.0f, 0.0f, 1.0f));

            for (uint i = 0; i < mesh.VertexCount; ++i)
            {
                Vector3 v;
                if (skinner != null && mesh.HasBones)
                {
                    skinner.GetTransformedVertexPosition(node, mesh, i, out v);
                }
                else
                {
                    v = AssimpToOpenTk.FromVector(mesh.Vertices[(int)i]);
                }
                v = Vector4.Transform(new Vector4(v, 1.0f), transform).Xyz; // Skip dividing by W component. It should always be 1, here.

                Vector3 n;
                if (skinner != null)
                {
                    skinner.GetTransformedVertexNormal(node, mesh, i, out n);
                }
                else
                {
                    n = AssimpToOpenTk.FromVector(mesh.Normals[(int)i]);
                }
                n = Vector4.Transform(new Vector4(n, 0.0f), normalMatrix).Xyz; // Toss the W component. It is non-sensical for normals.
                n.Normalize();

                GL.Vertex3(v);
                GL.Vertex3(v + n * scale);
            }
            GL.End();

            GL.Disable(EnableCap.ColorMaterial);
        }
Esempio n. 3
0
        public static void DrawNormals(Node node, int meshIndex, Mesh mesh, CpuSkinningEvaluator skinner, float invGlobalScale)
        {
            if (!mesh.HasNormals)
            {
                return;
            }
            // Scale by scene size because the scene will be resized to fit
            // the unit box but the normals should have a fixed length
            var scale = invGlobalScale * 0.05f;

            GL.Begin(BeginMode.Lines);

            GL.Disable(EnableCap.Lighting);
            GL.Disable(EnableCap.Texture2D);
            GL.Enable(EnableCap.ColorMaterial);

            GL.Color4(new Color4(0.0f, 1.0f, 0.0f, 1.0f));

            for (uint i = 0; i < mesh.VertexCount; ++i)
            {
                Vector3 v;
                if (skinner != null && mesh.HasBones)
                {
                    skinner.GetTransformedVertexPosition(node, meshIndex, i, out v);
                }
                else
                {
                    v = AssimpToOpenTk.FromVector(mesh.Vertices[(int)i]);
                }

                Vector3 n;
                if (skinner != null)
                {
                    skinner.GetTransformedVertexNormal(node, meshIndex, i, out n);
                }
                else
                {
                    n = AssimpToOpenTk.FromVector(mesh.Normals[(int)i]);
                }

                GL.Vertex3(v);
                GL.Vertex3(v + n * scale);
            }
            GL.End();

            GL.Disable(EnableCap.ColorMaterial);
        }
            /// <summary>
            /// Internal method to (re-)cache all transformed vertex positions and normals
            /// </summary>
            private void Cache()
            {
                var boneMatrices = _scene.SceneAnimator.GetBoneMatricesForMesh(_lastNode, _source);

                // update entire mesh
                for (int i = 0; i < _cachedPositions.Length; ++i)
                {
                    var v = AssimpToOpenTk.FromVector(_source.Vertices[i]);
                    EvaluateBoneInfluences(ref v, (uint)i, boneMatrices, out _cachedPositions[i]);
                }
                for (int i = 0; i < _cachedNormals.Length; ++i)
                {
                    var n = AssimpToOpenTk.FromVector(_source.Normals[i]);
                    EvaluateBoneInfluences(ref n, (uint)i, boneMatrices, out _cachedNormals[i], true);
                }

                _dirty = false;
            }
        /// <summary>
        /// Draw a mesh using either its given material or a transparent "ghost" material.
        /// </summary>
        /// <param name="node">Current node</param>
        /// <param name="animated">Specifies whether animations should be played</param>
        /// <param name="showGhost">Indicates whether to substitute the mesh' material with a
        /// "ghost" surrogate material that allows looking through the geometry.</param>
        /// <param name="index">Mesh index in the scene</param>
        /// <param name="mesh">Mesh instance</param>
        /// <param name="flags"> </param>
        /// <returns></returns>
        protected override bool InternDrawMesh(Node node, bool animated, bool showGhost, int index, Mesh mesh, RenderFlags flags)
        {
            if (showGhost)
            {
                Owner.MaterialMapper.ApplyGhostMaterial(mesh, Owner.Raw.Materials[mesh.MaterialIndex],
                                                        flags.HasFlag(RenderFlags.Shaded), flags.HasFlag(RenderFlags.ForceTwoSidedLighting));
            }
            else
            {
                Owner.MaterialMapper.ApplyMaterial(mesh, Owner.Raw.Materials[mesh.MaterialIndex],
                                                   flags.HasFlag(RenderFlags.Textured),
                                                   flags.HasFlag(RenderFlags.Shaded), flags.HasFlag(RenderFlags.ForceTwoSidedLighting));
            }

            if (GraphicsSettings.Default.BackFaceCulling)
            {
                GL.FrontFace(FrontFaceDirection.Ccw);
                GL.CullFace(CullFaceMode.Back);
                GL.Enable(EnableCap.CullFace);
            }
            else
            {
                GL.Disable(EnableCap.CullFace);
            }

            var hasColors    = mesh.HasVertexColors(0);
            var hasTexCoords = mesh.HasTextureCoords(0);

            var skinning = mesh.HasBones && animated;

            foreach (var face in mesh.Faces)
            {
                BeginMode faceMode;
                switch (face.IndexCount)
                {
                case 1:
                    faceMode = BeginMode.Points;
                    break;

                case 2:
                    faceMode = BeginMode.Lines;
                    break;

                case 3:
                    faceMode = BeginMode.Triangles;
                    break;

                default:
                    faceMode = BeginMode.Polygon;
                    break;
                }

                GL.Begin(faceMode);
                for (var i = 0; i < face.IndexCount; i++)
                {
                    var indice = face.Indices[i];
                    if (hasColors)
                    {
                        var vertColor = AssimpToOpenTk.FromColor(mesh.VertexColorChannels[0][indice]);
                        GL.Color4(vertColor);
                    }
                    if (mesh.HasNormals)
                    {
                        Vector3 normal;
                        if (skinning)
                        {
                            Skinner.GetTransformedVertexNormal(node, mesh, (uint)indice, out normal);
                        }
                        else
                        {
                            normal = AssimpToOpenTk.FromVector(mesh.Normals[indice]);
                        }

                        GL.Normal3(normal);
                    }
                    if (hasTexCoords)
                    {
                        var uvw = AssimpToOpenTk.FromVector(mesh.TextureCoordinateChannels[0][indice]);
                        GL.TexCoord2(uvw.X, 1 - uvw.Y);
                    }

                    Vector3 pos;
                    if (skinning)
                    {
                        Skinner.GetTransformedVertexPosition(node, mesh, (uint)indice, out pos);
                    }
                    else
                    {
                        pos = AssimpToOpenTk.FromVector(mesh.Vertices[indice]);
                    }
                    GL.Vertex3(pos);
                }
                GL.End();
            }
            GL.Disable(EnableCap.CullFace);
            return(skinning);
        }
Esempio n. 6
0
        public static void DrawBoundingBox(Node node, int meshIndex, Mesh mesh, CpuSkinningEvaluator skinner)
        {
            GL.Disable(EnableCap.Lighting);
            GL.Disable(EnableCap.Texture2D);
            GL.Enable(EnableCap.ColorMaterial);

            GL.Color4(new Color4(1.0f, 0.0f, 0.0f, 1.0f));

            var min = new Vector3(1e10f, 1e10f, 1e10f);
            var max = new Vector3(-1e10f, -1e10f, -1e10f);

            for (uint i = 0; i < mesh.VertexCount; ++i)
            {
                Vector3 tmp;
                if (skinner != null && mesh.HasBones)
                {
                    skinner.GetTransformedVertexPosition(node, mesh, i, out tmp);
                }
                else
                {
                    tmp = AssimpToOpenTk.FromVector(mesh.Vertices[(int)i]);
                }

                min.X = Math.Min(min.X, tmp.X);
                min.Y = Math.Min(min.Y, tmp.Y);
                min.Z = Math.Min(min.Z, tmp.Z);

                max.X = Math.Max(max.X, tmp.X);
                max.Y = Math.Max(max.Y, tmp.Y);
                max.Z = Math.Max(max.Z, tmp.Z);
            }

            GL.Begin(BeginMode.LineLoop);
            GL.Vertex3(min);
            GL.Vertex3(new Vector3(min.X, max.Y, min.Z));
            GL.Vertex3(new Vector3(min.X, max.Y, max.Z));
            GL.Vertex3(new Vector3(min.X, min.Y, max.Z));
            GL.End();

            GL.Begin(BeginMode.LineLoop);
            GL.Vertex3(new Vector3(max.X, min.Y, min.Z));
            GL.Vertex3(new Vector3(max.X, max.Y, min.Z));
            GL.Vertex3(new Vector3(max.X, max.Y, max.Z));
            GL.Vertex3(new Vector3(max.X, min.Y, max.Z));
            GL.End();

            GL.Begin(BeginMode.Lines);
            GL.Vertex3(min);
            GL.Vertex3(new Vector3(max.X, min.Y, min.Z));

            GL.Vertex3(new Vector3(min.X, max.Y, min.Z));
            GL.Vertex3(new Vector3(max.X, max.Y, min.Z));

            GL.Vertex3(new Vector3(min.X, max.Y, max.Z));
            GL.Vertex3(new Vector3(max.X, max.Y, max.Z));

            GL.Vertex3(new Vector3(min.X, min.Y, max.Z));
            GL.Vertex3(new Vector3(max.X, min.Y, max.Z));
            GL.End();

            GL.Disable(EnableCap.ColorMaterial);
        }