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; }
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; }