Ejemplo n.º 1
0
            public TrefoilKnotBuilder(IOpenGLObjectFactory objectFactory, int slices, int stacks, float ra, float rb, float rc, float rd, float[] c)
            {
                (float[] attributes, uint[] indices) = new TrefoilKnot(slices, stacks, ra, rb, rc, rd, c).Create();
                int tuple_size = 12;

                ModelNode node = new ModelNode(objectFactory);

                _model._root_node = node;
                node.ModelMatrix  = Matrix4.Identity;
                AABB mesh_box = new AABB();

                // extend bounding box by vertices
                for (int i = 0; i < attributes.Length; i += tuple_size)
                {
                    Vector3 vertex = new Vector3(attributes[i], attributes[i + 1], attributes[i + 2]);
                    mesh_box          = mesh_box | vertex;
                    _model._scene_box = _model._scene_box | vertex;
                }

                // create Mesh
                OpenTK_library.Scene.Mesh mesh = new OpenTK_library.Scene.Mesh();
                mesh.TupleSize = (uint)tuple_size;
                mesh.Box       = mesh_box;
                node.Add(mesh);

                mesh.VertexAttribute = (0, 3);
                mesh.NormalAttribute = (3, 3);
                mesh.AddTextureAttrib((6, 2));
                mesh.AddColorAttrib((8, 4));

                TVertexFormat[] format =
                {
                    new TVertexFormat(0, vertex_index,   3, 0, false),
                    new TVertexFormat(0, normal_index,   3, 3, false),
                    new TVertexFormat(0, texture0_index, 2, 6, false),
                    new TVertexFormat(0,              2, 4, 8, false),
                };

                // setup vertex arrays and index array
                var vao = openGLFactory.NewVertexArrayObject();

                vao.AppendVertexBuffer(0, (int)tuple_size, attributes);
                vao.Create(format, indices);

                mesh.FaceSize    = 3;
                mesh.VertexArray = vao;
            }
Ejemplo n.º 2
0
            private void CreateBuffers(Node assimpnode, ModelNode parent_node, ref Matrix4x4 model_matrix)
            {
                // create new mesh
                ModelNode node = new ModelNode(_openGLFactory);

                if (parent_node != null)
                {
                    parent_node.AddChild(node);
                }
                else
                {
                    _model._root_node = node;
                }

                // set model matrix
                Matrix4x4 mm = assimpnode.Transform;

                node.ModelMatrix = new Matrix4(
                    mm.A1, mm.A2, mm.A3, mm.A4,
                    mm.B1, mm.B2, mm.B3, mm.B4,
                    mm.C1, mm.C2, mm.C3, mm.C4,
                    mm.D1, mm.D2, mm.D3, mm.D4);

                // combined model matrix
                Matrix4x4 prev_model    = model_matrix;
                Matrix4x4 new_transform = assimpnode.Transform;

                model_matrix = new_transform * model_matrix; // ? has this to be reversed link in OpneTK?

                if (assimpnode.HasMeshes)
                {
                    foreach (int index in assimpnode.MeshIndices)
                    {
                        Assimp.Mesh assimpmesh = _assimpmodel.Meshes[index];
                        AABB        mesh_box   = new AABB();

                        // extend bounding box by vertices
                        for (int i = 0; i < assimpmesh.VertexCount; i++)
                        {
                            Vector3D tmp = assimpmesh.Vertices[i];
                            mesh_box = mesh_box | new Vector3(tmp.X, tmp.Y, tmp.Z);

                            tmp = model_matrix * tmp;
                            _model._scene_box = _model._scene_box | new Vector3(tmp.X, tmp.Y, tmp.Z);
                        }

                        // create Mesh
                        uint tuple_index = 0;
                        List <TVertexFormat> formalist = new List <TVertexFormat>();

                        OpenTK_library.Scene.Mesh mesh = new OpenTK_library.Scene.Mesh();
                        mesh.Box = mesh_box;
                        node.Add(mesh);

                        // specify vertices
                        mesh.VertexAttribute = (tuple_index, 3);
                        formalist.Add(new TVertexFormat(0, vertex_index, 3, (int)tuple_index, false));
                        tuple_index += 3;

                        // specify normals
                        if (assimpmesh.HasNormals)
                        {
                            mesh.NormalAttribute = (tuple_index, 3);
                            formalist.Add(new TVertexFormat(0, normal_index, 3, (int)tuple_index, false));
                            tuple_index += 3;
                        }

                        // specify bi-normals and tangents
                        if (assimpmesh.HasTangentBasis)
                        {
                            mesh.BinormalAttribute = (tuple_index, 3);
                            formalist.Add(new TVertexFormat(0, binormal_index, 3, (int)tuple_index, false));
                            tuple_index += 3;

                            mesh.TangentAttribute = (tuple_index, 3);
                            formalist.Add(new TVertexFormat(0, tangent_index, 3, (int)tuple_index, false));
                            tuple_index += 3;
                        }

                        // specify texture channels
                        for (int textur_channel = 0; assimpmesh.HasTextureCoords(textur_channel); ++textur_channel)
                        {
                            mesh.AddTextureAttrib((tuple_index, 3));
                            int attr_i = textur_channel == 0 ? texture0_index : (textureN_index + textur_channel - 1);
                            formalist.Add(new TVertexFormat(0, attr_i, 3, (int)tuple_index, false));
                            tuple_index += 3;
                        }

                        // specify color channels
                        for (int color_channel = 0; assimpmesh.HasVertexColors(color_channel); ++color_channel)
                        {
                            mesh.AddColorAttrib((tuple_index, 4));
                            int attr_i = color_channel == 0 ? color0_index : (colorN_index + color_channel - 1);
                            formalist.Add(new TVertexFormat(0, attr_i, 4, (int)tuple_index, false));
                            tuple_index += 4;
                        }

                        // TODO $$$ bones
                        if (assimpmesh.HasBones)
                        {
                            // [...]
                            Console.WriteLine("bones not yet implemented");
                        }

                        // set tuple size
                        mesh.TupleSize = tuple_index;

                        // setup index buffer
                        List <float> attributes = new List <float>();
                        List <uint>  indices    = new List <uint>();
                        uint         elem_index = 0;
                        foreach (Face face in assimpmesh.Faces)
                        {
                            if (face.IndexCount < 3)
                            {
                                continue; // lines?
                            }
                            for (uint i = 2; i < (uint)face.IndexCount; i++)
                            {
                                indices.Add(elem_index);
                                indices.Add(elem_index + 1);
                                indices.Add(elem_index + i);
                            }
                            elem_index += (uint)face.IndexCount;

                            for (int i = 0; i < face.IndexCount; i++)
                            {
                                int ei = face.Indices[i];

                                // add vertex attribute
                                var vertex = assimpmesh.Vertices[ei];
                                attributes.Add(vertex.X);
                                attributes.Add(vertex.Y);
                                attributes.Add(vertex.Z);

                                // add normals
                                if (assimpmesh.HasNormals)
                                {
                                    var normal = assimpmesh.Normals[ei];
                                    attributes.Add(normal.X);
                                    attributes.Add(normal.Y);
                                    attributes.Add(normal.Z);
                                }

                                // add bi-normals and tangents
                                if (assimpmesh.HasTangentBasis)
                                {
                                    var binormal = assimpmesh.BiTangents[ei];
                                    attributes.Add(binormal.X);
                                    attributes.Add(binormal.Y);
                                    attributes.Add(binormal.Z);

                                    var tangent = assimpmesh.Tangents[ei];
                                    attributes.Add(tangent.X);
                                    attributes.Add(tangent.Y);
                                    attributes.Add(tangent.Z);
                                }

                                // add texture coordinates
                                for (int textur_channel = 0; assimpmesh.HasTextureCoords(textur_channel); ++textur_channel)
                                {
                                    var uvw = assimpmesh.TextureCoordinateChannels[textur_channel][ei];
                                    attributes.Add(uvw.X);
                                    attributes.Add(uvw.Y);
                                    attributes.Add(uvw.Z);
                                }

                                // add color attributes
                                for (int color_channel = 0; assimpmesh.HasVertexColors(color_channel); ++color_channel)
                                {
                                    var vertColor = assimpmesh.VertexColorChannels[color_channel][ei];
                                    attributes.Add(vertColor.R);
                                    attributes.Add(vertColor.G);
                                    attributes.Add(vertColor.B);
                                    attributes.Add(vertColor.A);
                                }
                            }
                        }

                        // setup vertex arrays and index array
                        TVertexFormat[] format = formalist.ToArray();
                        var             vao    = _openGLFactory.NewVertexArrayObject();
                        vao.AppendVertexBuffer(0, (int)tuple_index, attributes.ToArray());
                        vao.Create(format, indices.ToArray());

                        mesh.FaceSize    = 3;
                        mesh.VertexArray = vao;
                    }
                }

                for (int i = 0; i < assimpnode.ChildCount; i++)
                {
                    CreateBuffers(assimpnode.Children[i], node, ref model_matrix);
                }
                model_matrix = prev_model;
            }