public void TestMeshPartPool()
        {
            XNAGame game = new XNAGame();

            game.DrawFps = true;

            var pool = new MeshPartPool();

            game.AddXNAObject(pool);

            RAMMeshPart meshPart = new RAMMeshPart();

            meshPart.SetGeometryData(MeshPartGeometryData.CreateTestSquare());

            DefaultModelShader shader = null;

            VertexDeclaration decl = null;

            game.InitializeEvent += delegate
            {
                decl   = TangentVertexExtensions.CreateVertexDeclaration(game);
                shader = new DefaultModelShader(game, new EffectPool());

                shader.DiffuseColor = Color.Red.ToVector4();
                shader.Technique    = DefaultModelShader.TechniqueType.Colored;
            };

            game.DrawEvent += delegate
            {
                game.GraphicsDevice.RenderState.CullMode = CullMode.None;
                game.GraphicsDevice.VertexDeclaration    = decl;

                shader.ViewProjection = game.Camera.ViewProjection;

                shader.World = Matrix.CreateTranslation(Vector3.Right * 0 * 3) * Matrix.CreateScale(10);
                shader.DrawPrimitives(delegate
                {
                    var vb          = pool.GetVertexBuffer(meshPart);
                    var ib          = pool.GetIndexBuffer(meshPart);
                    var vertexCount =
                        meshPart.GetGeometryData().GetSourceVector3(MeshPartGeometryData.Semantic.Position).Length;

                    game.GraphicsDevice.Vertices[0].SetSource(vb, 0, TangentVertex.SizeInBytes);
                    game.GraphicsDevice.Indices = ib;
                    game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, vertexCount, 0, vertexCount / 3);
                });
            };

            game.Run();
        }
        public MeshCoreData.Part CreateMeshPart(OBJGroup.SubObject sub)
        {
            if (sub.Faces.Count == 0)
            {
                return(null);
            }


            Vector3[] positions = new Vector3[sub.Faces.Count * 3];
            Vector3[] normals   = new Vector3[sub.Faces.Count * 3];
            Vector2[] texcoords = new Vector2[sub.Faces.Count * 3];


            // Note that faces are flipped in this piece of code!!!

            for (int k = 0; k < sub.Faces.Count; k++)
            {
                var face = sub.Faces[k];
                positions[k * 3 + 0] = importer.Vertices[face.V1.Position];
                positions[k * 3 + 1] = importer.Vertices[face.V3.Position];
                positions[k * 3 + 2] = importer.Vertices[face.V2.Position];

                normals[k * 3 + 0] = importer.Normals[face.V1.Normal];
                normals[k * 3 + 1] = importer.Normals[face.V3.Normal];
                normals[k * 3 + 2] = importer.Normals[face.V2.Normal];

                texcoords[k * 3 + 0] = new Vector2(importer.TexCoords[face.V1.TextureCoordinate].X,
                                                   1 - importer.TexCoords[face.V1.TextureCoordinate].Y);
                texcoords[k * 3 + 1] = new Vector2(importer.TexCoords[face.V3.TextureCoordinate].X,
                                                   1 - importer.TexCoords[face.V3.TextureCoordinate].Y);
                texcoords[k * 3 + 2] = new Vector2(importer.TexCoords[face.V2.TextureCoordinate].X,
                                                   1 - importer.TexCoords[face.V2.TextureCoordinate].Y);
            }


            TangentSolver solver   = new TangentSolver();
            var           tangents =
                solver.GenerateTangents(positions, normals, texcoords).Select(f => new Vector3(f.X, f.Y, f.Z)).ToArray();


            var positionsSource = new MeshPartGeometryData.Source();

            positionsSource.DataVector3 = positions;
            positionsSource.Semantic    = MeshPartGeometryData.Semantic.Position;
            var normalsSource = new MeshPartGeometryData.Source();

            normalsSource.DataVector3 = normals;
            normalsSource.Semantic    = MeshPartGeometryData.Semantic.Normal;
            var texcoordsSource = new MeshPartGeometryData.Source();

            texcoordsSource.DataVector2 = texcoords;
            texcoordsSource.Semantic    = MeshPartGeometryData.Semantic.Texcoord;
            var tangentsSource = new MeshPartGeometryData.Source();

            tangentsSource.DataVector3 = tangents;
            tangentsSource.Semantic    = MeshPartGeometryData.Semantic.Tangent;


            var part = new MeshCoreData.Part();

            part.MeshMaterial = materials[sub.Material];

            var meshPart = new RAMMeshPart();

            meshPart.GetGeometryData().Sources.Add(positionsSource);
            meshPart.GetGeometryData().Sources.Add(normalsSource);
            meshPart.GetGeometryData().Sources.Add(texcoordsSource);
            meshPart.GetGeometryData().Sources.Add(tangentsSource);

            part.MeshPart     = meshPart;
            part.ObjectMatrix = Matrix.Identity;

            return(part);
        }
        private void convertSubObjectRenderPart(RAMMesh mesh, OBJGroup.SubObject sub, ObjImporter importer, Dictionary <OBJMaterial, MeshCoreData.Material> materials)
        {
            if (sub.Faces.Count == 0)
            {
                return;
            }


            var meshCoreData = mesh.GetCoreData();

            Vector3[] positions = new Vector3[sub.Faces.Count * 3];
            Vector3[] normals   = new Vector3[sub.Faces.Count * 3];
            Vector2[] texcoords = new Vector2[sub.Faces.Count * 3];

            for (int k = 0; k < sub.Faces.Count; k++)
            {
                var face = sub.Faces[k];
                positions[k * 3 + 0] = importer.Vertices[face.V1.Position];
                positions[k * 3 + 1] = importer.Vertices[face.V2.Position];
                positions[k * 3 + 2] = importer.Vertices[face.V3.Position];

                normals[k * 3 + 0] = importer.Normals[face.V1.Normal];
                normals[k * 3 + 1] = importer.Normals[face.V2.Normal];
                normals[k * 3 + 2] = importer.Normals[face.V3.Normal];

                texcoords[k * 3 + 0] = new Vector2(importer.TexCoords[face.V1.TextureCoordinate].X, 1 - importer.TexCoords[face.V1.TextureCoordinate].Y);
                texcoords[k * 3 + 1] = new Vector2(importer.TexCoords[face.V2.TextureCoordinate].X, 1 - importer.TexCoords[face.V2.TextureCoordinate].Y);
                texcoords[k * 3 + 2] = new Vector2(importer.TexCoords[face.V3.TextureCoordinate].X, 1 - importer.TexCoords[face.V3.TextureCoordinate].Y);
            }


            TangentSolver solver   = new TangentSolver();
            var           tangents = solver.GenerateTangents(positions, normals, texcoords).Select(f => new Vector3(f.X, f.Y, f.Z)).ToArray();



            var positionsSource = new MeshPartGeometryData.Source();

            positionsSource.DataVector3 = positions;
            positionsSource.Semantic    = MeshPartGeometryData.Semantic.Position;
            var normalsSource = new MeshPartGeometryData.Source();

            normalsSource.DataVector3 = normals;
            normalsSource.Semantic    = MeshPartGeometryData.Semantic.Normal;
            var texcoordsSource = new MeshPartGeometryData.Source();

            texcoordsSource.DataVector2 = texcoords;
            texcoordsSource.Semantic    = MeshPartGeometryData.Semantic.Texcoord;
            var tangentsSource = new MeshPartGeometryData.Source();

            tangentsSource.DataVector3 = tangents;
            tangentsSource.Semantic    = MeshPartGeometryData.Semantic.Tangent;



            var part = new MeshCoreData.Part();

            part.MeshMaterial = materials[sub.Material];

            var meshPart = new RAMMeshPart();

            meshPart.GetGeometryData().Sources.Add(positionsSource);
            meshPart.GetGeometryData().Sources.Add(normalsSource);
            meshPart.GetGeometryData().Sources.Add(texcoordsSource);
            meshPart.GetGeometryData().Sources.Add(tangentsSource);

            part.MeshPart     = meshPart;
            part.ObjectMatrix = Matrix.Identity;

            meshCoreData.Parts.Add(part);
        }