/// <summary> /// 頂点バッファ生成構造体から初期化 /// </summary> /// <param name="buffer_desc"></param> public Prim(VertexBuffer.BufferDesc buffer_desc) { vertexNum_ = buffer_desc.data_size / buffer_desc.stride; vertexBuffer_ = new VertexBuffer(buffer_desc); WorldMatrix = Matrix.Identity; }
/// <summary> /// 矩形を追加する /// </summary> /// <param name="rect"></param> public void AddRect(ref Rect rect) { vertexNum_ = 6; // バッファデータ if ((vertexAttr_ & (uint)Shader.VertexAttr.TEXCOORD0) != 0) { // UV付き int vertex_stride = 20; int data_size = vertex_stride * vertexNum_; var vtx_ary = new[] { new { p = rect.leftTop, uv = new Vector2(0, 0) }, new { p = rect.rightBottom, uv = new Vector2(1, 1) }, new { p = new Vector3(rect.rightBottom.X, rect.leftTop.Y, rect.leftTop.Z), uv = new Vector2(1, 0) }, new { p = rect.leftTop, uv = new Vector2(0, 0) }, new { p = new Vector3(rect.leftTop.X, rect.rightBottom.Y, rect.leftTop.Z), uv = new Vector2(0, 1) }, new { p = rect.rightBottom, uv = new Vector2(1, 1) }, }; var vertices = new DataStream(data_size, true, true); foreach (var a in vtx_ary) { vertices.Write(a.p); vertices.Write(a.uv); } vertices.Position = 0; // 頂点バッファ生成 VertexBuffer.BufferDesc desc = new VertexBuffer.BufferDesc() { data = vertices, data_size = data_size, stride = vertex_stride }; vertexBuffer_ = new VertexBuffer(desc); vertices.Close(); } else { // positionのみ int vertex_stride = 12; int data_size = vertex_stride * vertexNum_; var vertices = new DataStream(data_size, true, true); vertices.Write(rect.leftTop); vertices.Write(rect.rightBottom); vertices.Write(new Vector3(rect.rightBottom.X, rect.leftTop.Y, rect.leftTop.Z)); vertices.Write(rect.leftTop); vertices.Write(new Vector3(rect.leftTop.X, rect.rightBottom.Y, rect.leftTop.Z)); vertices.Write(rect.rightBottom); vertices.Position = 0; // 頂点バッファ生成 VertexBuffer.BufferDesc desc = new VertexBuffer.BufferDesc() { data = vertices, data_size = data_size, stride = vertex_stride }; vertexBuffer_ = new VertexBuffer(desc); vertices.Close(); } }
public void AddVertex(Vector3[] vertices) { vertexNum_ = vertices.Length; // positionのみ int vertex_stride = 12; int data_size = vertex_stride * vertexNum_; var stream = new DataStream(data_size, true, true); foreach (var v in vertices) { stream.Write(v); } stream.Position = 0; // 頂点バッファ生成 VertexBuffer.BufferDesc desc = new VertexBuffer.BufferDesc() { data = stream, data_size = data_size, stride = vertex_stride }; vertexBuffer_ = new VertexBuffer(desc); stream.Close(); }
/// <summary> /// LoaderからMeshを生成する /// </summary> static void MeshLoad(Model model, Ext.MeshLoader loader, string fileName, float scaling, MMLParser mml) { model.FilePath = fileName; string baseDir = Path.GetDirectoryName(fileName); int numVertices = loader.m_Vertices.Count; int numIndices = loader.m_Indices.Count; // 頂点バッファ int elemNum; uint shaderAttr; if (loader.m_Vertices[0].GetType().Name == "MyVertex") { elemNum = 8; shaderAttr = (uint)(Shader.VertexAttr.POSITION | Shader.VertexAttr.NORMAL | Shader.VertexAttr.TEXCOORD0); } else { elemNum = 14; shaderAttr = (uint)(Shader.VertexAttr.POSITION | Shader.VertexAttr.NORMAL | Shader.VertexAttr.TEXCOORD0 | Shader.VertexAttr.TANGENT | Shader.VertexAttr.BITANGENT); } int stride = elemNum * sizeof(System.Single); int vertex_size = stride * numVertices; var vertices = new DataStream(vertex_size, true, true); foreach (var vertex in loader.m_Vertices) { vertices.Write(new Vector3(vertex.x * scaling, vertex.y * scaling, vertex.z * scaling)); vertices.Write(new Vector3(vertex.nx, vertex.ny, vertex.nz)); vertices.Write(new Vector2(vertex.u, vertex.v)); var bv = vertex as Ext.MyVertexBump; if (bv != null) { vertices.Write(new Vector3(bv.tx, bv.ty, bv.tz)); vertices.Write(new Vector3(bv.btx, bv.bty, bv.btz)); } } vertices.Position = 0; VertexBuffer.BufferDesc desc = new VertexBuffer.BufferDesc() { data = vertices, data_size = vertex_size, stride = stride }; model.vertexBuffer_ = new VertexBuffer(desc); vertices.Close(); // インデックスバッファ int index_size = 4 * numIndices; var indices = new DataStream(index_size, true, true); foreach (var index in loader.m_Indices) { indices.Write(index); } indices.Position = 0; model.indexBuffer_ = new IndexBuffer(indices, index_size); indices.Close(); model.indexNum_ = numIndices; // 以下マテリアル関係 { // テクスチャ Dictionary <string, string> textureList = loader.m_textureList; if (mml != null) { textureList = new Dictionary <string, string>(); foreach (var m in mml.Materials) { foreach (var t in m.Textures) { if (t.Path != null && t.Path != "") { textureList[t.Path] = t.Path; } } } } int texNum = textureList.Count; if (texNum > 0) { model.textures_ = new List <Texture>(texNum); } var textureDict = new Dictionary <string, int>(); model.textureDict_ = new Dictionary <int, string>(); int currentIdx = 0; foreach (var v in textureList) { try { string path = v.Value.Replace("file:///", ""); path = System.IO.Path.IsPathRooted(path) ? path : baseDir + "/" + path; model.textures_.Add(new Texture(path)); textureDict[v.Key] = currentIdx; model.textureDict_[currentIdx] = v.Key; currentIdx++; } catch { Console.WriteLine("テクスチャの読み込みに失敗しました."); } } // マテリアル List <Ext.MaterialObject> materialList = loader.m_materialList; if (mml != null) { materialList = new List <Ext.MaterialObject>(); // TODO:名前解決したほうがいい? foreach (var m in mml.Materials) { var mat = new Ext.MaterialObject(); mat.ID = m.Name; mat.textureID = new List <string>(); foreach (var s in m.Textures) { if (s.Path != null && s.Path != "") { mat.textureID.Add(s.Path); } } materialList.Add(mat); } } int material_num = materialList.Count; Material.ksMaterialStruct[] material_struct_list = new Material.ksMaterialStruct[material_num]; for (int i = 0; i < material_num; i++) { if (materialList[i].textureID.Count > 0) { // テクスチャあり material_struct_list[i].m_Type = (int)Material.MaterialType.TEXTURE_ONLY; material_struct_list[i].m_texID.Initialize(); for (int j = 0; j < materialList[i].textureID.Count; j++) { var t = materialList[i].textureID[j]; if (textureDict.ContainsKey(t)) { material_struct_list[i].m_texID[j] = textureDict[t]; } } } else { // テクスチャなし material_struct_list[i].m_Type = (int)Material.MaterialType.COLOR_ONLY; material_struct_list[i].color = new Color4(1.0f, 1.0f, 1.0f, 1.0f); } } // マテリアル実体 model.materials_ = new Material[material_num]; model.textureIdDict_ = new Dictionary <Material, Material.Index4>(); for (int i = 0; i < material_num; i++) { model.materials_[i] = new Material(model, ref material_struct_list[i], model.textures_); model.materials_[i].Name = materialList[i].ID; // 気持ち悪いので何とかしたいところ(ksmdlのサポートを切れば...) model.materials_[i].SetShader(ShaderManager.DefaultShader, shaderAttr); if (material_struct_list[i].m_Type == (int)Material.MaterialType.TEXTURE_ONLY) { model.textureIdDict_[model.materials_[i]] = material_struct_list[i].m_texID; } if (mml != null) { // パラメータ model.materials_[i].userParams_ = mml.Materials[i].Params; model.materials_[i].userParamSize_ = mml.ParamSize; } } // パラメータを持っていないデータを読んだ場合適当な値を生成しておく if (mml == null) { MaterialParamLoader mloader = new MaterialParamLoader(model.materials_); mloader.Load(null); } // マテリアルエディタ時は調整用パラメータを生成する if (AutoCreateMaterialUserParam) { for (int i = 0; i < material_num; i++) { model.materials_[i].InitializeTextureParams(ref material_struct_list[i]); } } // 1ノードで複数サブセットという形にしておく int subsetNum = loader.m_subsetList.Count; model.nodes_ = new Node[1]; model.nodes_[0] = new Node(subsetNum); for (int i = 0; i < loader.m_subsetList.Count; i++) { var subset = loader.m_subsetList[i]; int startIdx = subset.startIndex; int endIdx = subset.endIndex; model.nodes_[0].Subsets[i].startIndex = startIdx; model.nodes_[0].Subsets[i].endIndex = endIdx; model.nodes_[0].Subsets[i].materialIndex = materialList.FindIndex(0, c => c.ID == subset.material); } } }
static void LoadFromksmdl(Model model, string fileName) { using (var stream = new System.IO.FileStream(fileName, System.IO.FileMode.Open, FileAccess.Read)) { byte[] data = new byte[stream.Length]; stream.Read(data, 0, (int)stream.Length); MemoryStream s = new MemoryStream(data); // byte配列からポインタを取得 var handle = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr ptr = handle.AddrOfPinnedObject(); ksModelHeader header = (ksModelHeader)Marshal.PtrToStructure(ptr, typeof(ksModelHeader)); int offset = Marshal.SizeOf(header); int stride = Model.GetVertexBufferStride(header.bufferBit); // 頂点バッファ IntPtr curPtr = ptr + offset; int vertex_size = stride * header.vertexNum; var vertices = new DataStream(curPtr, vertex_size, true, true); VertexBuffer.BufferDesc desc = new VertexBuffer.BufferDesc() { data = vertices, data_size = vertex_size, stride = stride }; model.vertexBuffer_ = new VertexBuffer(desc); vertices.Close(); // インデックスバッファ curPtr = curPtr + vertex_size; int index_size = sizeof(int) * header.indexNum; var indices = new DataStream(curPtr, index_size, true, true); model.indexBuffer_ = new IndexBuffer(indices, index_size); indices.Close(); model.indexNum_ = header.indexNum; // マテリアル curPtr = curPtr + index_size; int material_num = Marshal.ReadInt32(curPtr); curPtr = curPtr + sizeof(int); Material.ksMaterialStruct[] material_struct_list = new Material.ksMaterialStruct[material_num]; for (int i = 0; i < material_num; i++) { material_struct_list[i] = (Material.ksMaterialStruct)Marshal.PtrToStructure(curPtr, typeof(Material.ksMaterialStruct)); { // ksmdlは現状1枚しかテクスチャに対応していない(設定しない分を-1で埋める) if (material_struct_list[i].m_Type == (int)(Material.MaterialType.TEXTURE_ONLY)) { for (int j = 1; j < 4; j++) { material_struct_list[i].m_texID[j] = -1; } } } curPtr += Marshal.SizeOf(typeof(Material.ksMaterialStruct)); } // ノード model.nodes_ = new Node[header.nodeNum]; for (int i = 0; i < header.nodeNum; ++i) { model.nodes_[i] = Node.CreateByBinary(ref curPtr); } // 階層情報 model.controlNode_ = new Node(); Node sublingNode = null; int hierarchyNum = Marshal.ReadInt32(curPtr); curPtr += 4; for (int i = 0; i < hierarchyNum; i++) { if (i == 0) { ReadNodeHierarchy(ref curPtr, model.controlNode_, model.nodes_, true); sublingNode = model.controlNode_.Child; } else { ReadNodeHierarchy(ref curPtr, sublingNode, model.nodes_, false); sublingNode = sublingNode.Subling; } } // テクスチャ int texture_num = Marshal.ReadInt32(curPtr); curPtr += 4; if (texture_num > 0) { model.textures_ = new List <Texture>(texture_num); for (int i = 0; i < texture_num; i++) { int size = Marshal.ReadInt32(curPtr); curPtr += 4; model.textures_[i] = new Texture(curPtr); curPtr += size; } } // マテリアル実体 model.materials_ = new Material[material_num]; for (int i = 0; i < material_num; i++) { model.materials_[i] = new Material(model, ref material_struct_list[i], model.textures_); //仮 uint attr = (uint)(Shader.VertexAttr.POSITION | Shader.VertexAttr.NORMAL); attr |= (texture_num != 0) ? (uint)Shader.VertexAttr.TEXCOORD0 : 0; if ((header.bufferBit & (uint)BufferBit.SkinController) != 0) { attr |= (uint)Shader.VertexAttr.SKIN; } model.materials_[i].SetShader(ShaderManager.DefaultShader, attr); } // ハンドル解放 handle.Free(); } }