public BufferDataInfo(ESemantic s) { X = new PassDataInfo(ESlot.None, s, EPass.X); Y = new PassDataInfo(ESlot.None, s, EPass.Y); Z = new PassDataInfo(ESlot.None, s, EPass.Z); W = new PassDataInfo(ESlot.None, s, EPass.W); }
public MeshData Convert(string newMeshName) { int id = CheckValid(); if (id != 0) { Debug.LogError("转换失败:" + GetValidInfo(id)); return(null); } MeshData newMesh = new MeshData(newMeshName); MeshData slotmesh = SlotA == null ? SlotB : SlotA; if (slotmesh == null) { slotmesh = SlotC; if (slotmesh == null) { slotmesh = SlotD; } } if (slotmesh == null) { return(null); } int vertexNum = slotmesh.GetVertexCount(); foreach (var pair in BufferInfos) { BufferDataInfo buff = pair.Value; ESemantic s = pair.Key; Vector4[] data = new Vector4[vertexNum]; int dim = 0; for (int i = 0; i < 4; i++) { var pass = buff[i]; if (pass.Slot == ESlot.None || pass.Semantic == ESemantic.UnKnown) { break; } var slot = this[(int)pass.Slot - 1]; for (int j = 0; j < vertexNum; j++) { data[j][i] = (slot.Buffers[pass.Semantic].mData[j])[(int)pass.Pass]; } dim = i + 1; } if (dim > 0) { newMesh.AddDataRange(s, data, dim); } } newMesh.AddTrangle(slotmesh.Trangles.ToArray()); return(newMesh); }
private bool DrawBufferInfo(ESemantic s, ConvertStrategy.BufferDataInfo info) { EditorGUILayout.BeginHorizontal(); { if (GUILayout.Button("R", EditorStyles.toolbarButton, GUILayout.Width(30))) { return(false); } var slot = (ConvertStrategy.ESlot)EditorGUILayout.EnumPopup(ConvertStrategy.ESlot.None, GUILayout.Width(80)); if (slot != ConvertStrategy.ESlot.None) { info.X.Slot = slot; info.Y.Slot = slot; if ((int)s < (int)ESemantic.Coord0) { info.Z.Slot = slot; } if (s == ESemantic.Color) { info.W.Slot = slot; } } var semantic = (ESemantic)EditorGUILayout.EnumPopup(ESemantic.UnKnown, GUILayout.Width(80)); if (semantic != ESemantic.UnKnown) { info.X.Semantic = semantic; info.Y.Semantic = semantic; info.Z.Semantic = semantic; info.W.Semantic = semantic; } bool used = info.X.IsValid(); if (!used) { GUILayout.Label(s.ToString() + ":", GUILayout.Width(80)); } else { GUILayout.Label(s.ToString() + ":", EditorStyles.boldLabel, GUILayout.Width(80)); } DrawPassDataInfo(info.X, "X", used); GUILayout.Space(20); used &= info.Y.IsValid(); DrawPassDataInfo(info.Y, "Y", used); GUILayout.Space(20); used &= info.Z.IsValid(); DrawPassDataInfo(info.Z, "Z", used); GUILayout.Space(20); used &= info.W.IsValid(); DrawPassDataInfo(info.W, "W", used); } EditorGUILayout.EndHorizontal(); return(true); }
public void AddDataRange(ESemantic s, IEnumerable <Vector4> datas, int dimension = 4) { VBuffer buff; if (!Buffers.TryGetValue(s, out buff)) { buff = new VBuffer(); Buffers.Add(s, buff); } buff.mData.AddRange(datas); buff.mDimension = Mathf.Max(buff.mDimension, dimension); }
public void AddData(ESemantic s, Vector4 data, int dimension = 4) { VBuffer buff; if (!Buffers.TryGetValue(s, out buff)) { buff = new VBuffer(); Buffers.Add(s, buff); } buff.mData.Add(data); buff.mDimension = Mathf.Max(buff.mDimension, dimension); }
private void AddData(ESemantic s, string[] elements) { Vector4 v = new Vector4(); for (int i = 1; i < elements.Length; i++) { if (i > 4) { break; } v[i - 1] = float.Parse(elements[i]); } mMesh.AddData(s, v, elements.Length - 1); }
public void OnGUI() { if (mMeshData == null) { return; } if (mStyles == null) { mStyles = new Styles(); } int vertexNum = mMeshData.GetVertexCount(); float height = this.position.height - 20; float width = 40; int viewItemNum = Mathf.FloorToInt(height / 18 - 1); //id scroll bar current = (int)GUI.VerticalScrollbar(new Rect(0, 0, 20, height + 3), current, viewItemNum, 0, vertexNum); int end = Mathf.Min(current + viewItemNum, vertexNum); int start = Mathf.Max(0, end - viewItemNum); EditorGUILayout.BeginHorizontal(); { GUILayout.Space(20); //draw id EditorGUILayout.BeginVertical(mStyles.mPreviewBox, GUILayout.Width(width), GUILayout.Height(height)); { EditorGUILayout.BeginHorizontal(mStyles.mOLTitle); { EditorGUILayout.LabelField(" id", EditorStyles.boldLabel, GUILayout.Width(width)); } EditorGUILayout.EndHorizontal(); for (int i = start; i < end; i++) { EditorGUILayout.LabelField(i.ToString(), EditorStyles.boldLabel, GUILayout.Width(width)); } } EditorGUILayout.EndVertical(); GUILayout.Space(1); DataPanelScroll = EditorGUILayout.BeginScrollView(DataPanelScroll); EditorGUILayout.BeginHorizontal(); { foreach (var pair in mMeshData.Buffers) { ESemantic s = pair.Key; MeshData.VBuffer buff = pair.Value; width = buff.mDimension * 100; EditorGUILayout.BeginVertical(mStyles.mPreviewBox, GUILayout.Width(width), GUILayout.Height(height)); { EditorGUILayout.BeginHorizontal(mStyles.mOLTitle); { EditorGUILayout.LabelField(" " + s.ToString(), EditorStyles.boldLabel, GUILayout.Width(width)); } EditorGUILayout.EndHorizontal(); for (int i = start; i < end; i++) { EditorGUILayout.BeginHorizontal(); for (int j = 0; j < buff.mDimension; j++) { EditorGUILayout.LabelField(buff.mData[i][j].ToString(), GUILayout.Width(90)); } EditorGUILayout.EndHorizontal(); } } EditorGUILayout.EndVertical(); } } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndScrollView(); } GUILayout.Label(mMeshData.GetInfo()); EditorGUILayout.EndHorizontal(); }
public PassDataInfo(ESlot slot, ESemantic s, EPass pass) { Slot = slot; Semantic = s; Pass = pass; }
public PassDataInfo() { Slot = ESlot.None; Semantic = ESemantic.UnKnown; Pass = EPass.W; }
private static void DecodeSource( Source src, ESemantic semantic, int offset, int set, int maxSets, BasePrimitive prim, int[] indices, Vertex[][] vertices, InfluenceDef[] infList, Matrix4 bindMatrix, Matrix4 invTranspBindMatrix) { var acc = src.TechniqueCommonElement.AccessorElement; int stride = (int)acc.Stride; int startIndex, pointIndex; float[] list = src.GetArrayElement <FloatArray>().StringContent.Values; for (int i = 0, x = 0; i < prim.PointCount; ++i, x += prim.InputElements.Length) { if (vertices[i] == null) { vertices[i] = new Vertex[maxSets]; } startIndex = (pointIndex = indices[x + offset]) * stride; Vertex vtx = vertices[i][set]; if (vtx == null) { vtx = new Vertex(); } switch (semantic) { case ESemantic.POSITION: Vec3 position = new Vec3( list[startIndex], list[startIndex + 1], list[startIndex + 2]); position = Vec3.TransformPosition(position, bindMatrix); vtx.Position = position; if (infList != null) { vtx.Influence = infList[pointIndex]; } break; case ESemantic.NORMAL: Vec3 normal = new Vec3( list[startIndex], list[startIndex + 1], list[startIndex + 2]); vtx.Normal = Vec3.TransformVector(normal, invTranspBindMatrix); break; case ESemantic.BINORMAL: case ESemantic.TEXBINORMAL: Vec3 binormal = new Vec3( list[startIndex], list[startIndex + 1], list[startIndex + 2]); vtx.Binormal = Vec3.TransformVector(binormal, invTranspBindMatrix); break; case ESemantic.TANGENT: case ESemantic.TEXTANGENT: Vec3 tangent = new Vec3( list[startIndex], list[startIndex + 1], list[startIndex + 2]); vtx.Tangent = Vec3.TransformVector(tangent, invTranspBindMatrix); break; case ESemantic.TEXCOORD: vtx.TexCoord = new Vec2( list[startIndex], ImportOptions.InvertTexCoordY ? 1.0f - list[startIndex + 1] : list[startIndex + 1]); break; case ESemantic.COLOR: vtx.Color = new ColorF4( list[startIndex], list[startIndex + 1], list[startIndex + 2], list[startIndex + 3]); break; } vertices[i][set] = vtx; } }
public static void DecodePrimitives( Geometry geo, Matrix4 bindMatrix, InfluenceDef[] infList, out VertexShaderDesc info, out List <VertexPrimitive> lines, out List <VertexPolygon> faces) { info = VertexShaderDesc.JustPositions(); lines = new List <VertexPrimitive>(); faces = new List <VertexPolygon>(); Source src; int boneCount = 0; if (infList != null) { HashSet <string> bones = new HashSet <string>(); foreach (InfluenceDef inf in infList) { for (int i = 0; i < inf.WeightCount; ++i) { bones.Add(inf.Weights[i].Bone); } } boneCount = bones.Count; } info.BoneCount = boneCount; var m = geo.MeshElement; if (m == null) { return; } Vertices vertsElem; foreach (var prim in m.PrimitiveElements) { Dictionary <ESemantic, int> semanticCounts = new Dictionary <ESemantic, int>(); Dictionary <ESemantic, Dictionary <int, Source> > inputSources = new Dictionary <ESemantic, Dictionary <int, Source> >(); Dictionary <ESemantic, Source> vertexInputSources = new Dictionary <ESemantic, Source>(); foreach (InputShared inp in prim.InputElements) { if (inp.CommonSemanticType == ESemantic.VERTEX) { vertsElem = inp.Source.GetElement <Vertices>(inp.Root); foreach (InputUnshared input in vertsElem.InputElements) { ESemantic semantic = input.CommonSemanticType; if (semanticCounts.ContainsKey(semantic)) { ++semanticCounts[semantic]; } else { semanticCounts.Add(semantic, 1); } src = input.Source.GetElement <Source>(vertsElem.Root); vertexInputSources[input.CommonSemanticType] = src; } continue; } else { ESemantic semantic = inp.CommonSemanticType; if (semanticCounts.ContainsKey(semantic)) { ++semanticCounts[semantic]; } else { semanticCounts.Add(semantic, 1); } src = inp.Source.GetElement <Source>(inp.Root); if (src != null) { if (!inputSources.ContainsKey(semantic)) { inputSources.Add(semantic, new Dictionary <int, Source>()); } int set = (int)inp.Set; if (!inputSources[semantic].ContainsKey(set)) { inputSources[semantic].Add(set, src); } else { inputSources[semantic][set] = src; } } } } info.MorphCount = 0; //Morphs are stored in separate geometry entries, so they need to be combined later info.HasNormals = semanticCounts.ContainsKey(ESemantic.NORMAL) && semanticCounts[ESemantic.NORMAL] > 0; bool hasTexBinormal = semanticCounts.ContainsKey(ESemantic.TEXBINORMAL) && semanticCounts[ESemantic.TEXBINORMAL] > 0; bool hasBinormal = semanticCounts.ContainsKey(ESemantic.BINORMAL) && semanticCounts[ESemantic.BINORMAL] > 0; info.HasBinormals = hasTexBinormal || hasBinormal; bool hasTexTangent = semanticCounts.ContainsKey(ESemantic.TEXTANGENT) && semanticCounts[ESemantic.TEXTANGENT] > 0; bool hasTangent = semanticCounts.ContainsKey(ESemantic.TANGENT) && semanticCounts[ESemantic.TANGENT] > 0; info.HasTangents = hasTexTangent || hasTangent; info.ColorCount = semanticCounts.ContainsKey(ESemantic.COLOR) ? semanticCounts[ESemantic.COLOR] : 0; info.TexcoordCount = semanticCounts.ContainsKey(ESemantic.TEXCOORD) ? semanticCounts[ESemantic.TEXCOORD] : 0; int maxSets = Math.Max(info.MorphCount + 1, Math.Max(info.ColorCount, info.TexcoordCount)); Vertex[][] vertices = new Vertex[prim.PointCount][]; int[] indices = prim?.IndicesElement?.StringContent?.Values; if (indices == null) { WriteLine("Mesh has no face indices. Mesh will be empty."); return; } Matrix4 invTranspBindMatrix = bindMatrix; if (info.HasNormals || info.HasBinormals || info.HasTangents) { invTranspBindMatrix.Invert(); invTranspBindMatrix.Transpose(); } foreach (var inp in prim.InputElements) { int set = (int)inp.Set; int offset = (int)inp.Offset; if (inp.CommonSemanticType == ESemantic.VERTEX) { foreach (ESemantic s in vertexInputSources.Keys) { src = vertexInputSources[s]; DecodeSource(src, s, offset, set, maxSets, prim, indices, vertices, infList, bindMatrix, invTranspBindMatrix); } } else { src = inputSources[inp.CommonSemanticType][set]; DecodeSource(src, inp.CommonSemanticType, offset, set, maxSets, prim, indices, vertices, infList, bindMatrix, invTranspBindMatrix); } } int setIndex = 0; switch (prim.Type) { case EColladaPrimitiveType.Lines: VertexLine[] linesTemp = new VertexLine[vertices.Length / 2]; for (int i = 0, x = 0; i < vertices.Length; i += 2, ++x) { linesTemp[x] = new VertexLine(vertices[i][setIndex], vertices[i + 1][setIndex]); } lines.AddRange(linesTemp); break; case EColladaPrimitiveType.Linestrips: lines.Add(new VertexLineStrip(false, vertices.Select(x => x[setIndex]).ToArray())); break; case EColladaPrimitiveType.Triangles: VertexTriangle[] tris = new VertexTriangle[vertices.Length / 3]; for (int i = 0, x = 0; i < vertices.Length; i += 3, ++x) { tris[x] = new VertexTriangle( vertices[i][setIndex], vertices[i + 1][setIndex], vertices[i + 2][setIndex]); } faces.AddRange(tris); break; case EColladaPrimitiveType.Trifans: faces.Add(new VertexTriangleFan(vertices.Select(x => x[setIndex]).ToArray())); break; case EColladaPrimitiveType.Tristrips: faces.Add(new VertexTriangleStrip(vertices.Select(x => x[setIndex]).ToArray())); break; case EColladaPrimitiveType.Polylist: Polylist polyListPrim = (Polylist)prim; PolyCounts countsElem = polyListPrim.PolyCountsElement; int[] counts = countsElem.StringContent.Values; VertexPolygon[] polys = new VertexPolygon[counts.Length]; for (int vtxIndex = 0, polyIndex = 0; polyIndex < counts.Length; ++polyIndex) { int count = counts[polyIndex]; Vertex[] verts = new Vertex[count]; for (int polyVtxIndex = 0; polyVtxIndex < count; ++polyVtxIndex, ++vtxIndex) { verts[polyVtxIndex] = vertices[vtxIndex][setIndex]; } polys[polyIndex] = new VertexPolygon(verts); } faces.AddRange(polys); break; default: case EColladaPrimitiveType.Polygons: WriteLine($"Primitive type '{prim.Type.ToString()}' not supported. Mesh will be empty."); break; } } }
public Mesh ToMesh(bool inverseX = false) { Mesh mesh = new Mesh(); mesh.name = Name; foreach (var pair in Buffers) { ESemantic s = pair.Key; VBuffer buff = pair.Value; switch (s) { case ESemantic.Position: mesh.SetVertices(vector4to3(buff.mData, inverseX)); break; case ESemantic.Normal: mesh.SetNormals(vector4to3(buff.mData)); break; case ESemantic.Color: mesh.SetColors(vector4toColor(buff.mData)); break; case ESemantic.Tangent: mesh.SetTangents(buff.mData); break; case ESemantic.Coord0: case ESemantic.Coord1: case ESemantic.Coord2: case ESemantic.Coord3: case ESemantic.Coord4: int c = (int)s - (int)ESemantic.Coord0; switch (buff.mDimension) { case 2: mesh.SetUVs(c, vector4to2(buff.mData)); break; case 3: mesh.SetUVs(c, vector4to3(buff.mData)); break; case 4: mesh.SetUVs(c, buff.mData); break; default: Debug.LogWarning("buffer dimention warning:" + s + "-" + buff.mDimension); break; } break; default: Debug.LogWarning("unsuport buffer:" + s); break; } } int[] triangles = new int[Trangles.Count]; for (int i = 0; i < Trangles.Count / 3; i++) { triangles[i * 3] = Trangles[i * 3]; if (inverseX) { triangles[i * 3 + 1] = Trangles[i * 3 + 2]; triangles[i * 3 + 2] = Trangles[i * 3 + 1]; } else { triangles[i * 3 + 1] = Trangles[i * 3 + 1]; triangles[i * 3 + 2] = Trangles[i * 3 + 2]; } } mesh.SetTriangles(triangles, 0); return(mesh); }