示例#1
0
        public static Geometry Polylist(string geoID, string geoName, string matName, GeometryDataType[] dataTypes, float[][] data, ulong[] channels, Semantic[] semantics, ulong[] dataSources, ulong[] sets, int[] vCount, int[] primitives)
        {
            int  maxLength = Math.Min((int)data.Length, (int)dataTypes.Length);
            Mesh mesh      = new Mesh();

            mesh.source = new Source[0];
            Polylist polylist = new Polylist((ulong)vCount.Length, matName, vCount, primitives);

            polylist.input = new InputOffset[0];

            // ! ! ! !
            // separate adding data and adding semantic inputs into two loops/steps
            //  -> add a GeometryDataType enumeration to identify each data array as a specific data (Vertex, Normal, Texcoord, Colors)
            //  -> and the Semantic which generates the "input" types for the composed vertex data which is generated by the primitive list
            for (int i = 0; i < maxLength; i++)
            {
                DAEGeometry.AppendDataSource(mesh, geoName, dataTypes[i], data[i], channels[i]);
            }

            for (int i = 0; i < maxLength; i++)
            {
                DAEGeometry.AppendPolylistSemantic(polylist, geoName, semantics[i], dataSources[i], sets[i]);
            }


            mesh.primitives = new object[] { polylist };
            Geometry geo = new Geometry(geoID, geoName, mesh);

            return(geo);
        }
示例#2
0
 private static ulong ExpandInput(Polylist polylist)
 {
     InputOffset[] inputs = polylist.input;
     Array.Resize <InputOffset>(ref inputs, (int)inputs.Length + 1);
     polylist.input = inputs;
     return((ulong)(inputs.Length - 1));
 }
示例#3
0
        public static Geometry Polylist(string geoID, string geoName, string matName, float[] positions, float[] normals, float[] texcoords, float[] vertexColors, int[] vCount, int[] primitive)
        {
            int numSources = 1;

            if (normals != null)
            {
                numSources++;
            }
            if (texcoords != null)
            {
                numSources++;
            }
            if (vertexColors != null)
            {
                numSources++;
            }

            if ((positions == null ? true : positions.Length == 0))
            {
                throw new ArgumentException("Missing position data. Provide at least position data to use Polylist()", "positions");
            }
            Mesh mesh = new Mesh()
            {
                source = new Source[numSources]
            };
            Polylist polyList = new Polylist((ulong)vCount.Length, matName, vCount, primitive)
            {
                input = new InputOffset[numSources]
            };

            mesh.primitives = new object[] { polyList };
            ulong sInd = (ulong)0;

            mesh.source[sInd]    = Source.CreatePositions(geoName, positions);
            polyList.input[sInd] = new InputOffset("VERTEX", string.Concat("#", geoName, "-VERTEX", sInd));
            if (normals != null)
            {
                sInd++;
                mesh.source[sInd]    = Source.CreateNormals(geoName, 0, normals);
                polyList.input[sInd] = new InputOffset("NORMAL", string.Concat("#", geoName, "-Normal0", sInd));
            }
            if (texcoords != null)
            {
                sInd++;
                mesh.source[sInd]    = Source.CreateUVs(geoName, 0, texcoords);
                polyList.input[sInd] = new InputOffset("TEXCOORD", string.Concat("#", geoName, "-UV", sInd));
            }
            if (vertexColors != null)
            {
                sInd++;
                mesh.source[sInd]    = Source.CreateVertexColors(geoName, 0, vertexColors);
                polyList.input[sInd] = new InputOffset("COLOR", string.Concat("#", geoName, "-VERTEX_COLOR0", sInd));
            }
            mesh.vertices = DAEGeometry.GenerateVertices(geoName);
            Geometry geo = new Geometry(geoID, geoName, mesh);

            return(geo);
        }
示例#4
0
        // move to MeshDAE class (and make it an instance-method instead of static
        public static void AppendPolylist(string geoName, string matName, DAEGeometryInputSemanticInfo[] semanticsInfos, int[] vCount, int[] primitives, Mesh mesh)
        {
            if (mesh == null)
            {
                return;
            }

            ulong    polylistIndex = DAEGeometry.ExpandItems(mesh);
            Polylist polylist      = new Polylist((ulong)vCount.Length, matName, vCount, primitives);

            polylist.input = new InputOffset[0];

            for (int i = 0; i < semanticsInfos.Length; i++)
            {
                DAEGeometry.AppendPolylistSemantic(polylist, geoName, semanticsInfos[i].Semantic, semanticsInfos[i].DataSourceIndex, semanticsInfos[i].SetIndex);
            }

            mesh.primitives[polylistIndex] = polylist;
        }
示例#5
0
        private static void AppendPolylistSemantic(Polylist polylist, string geoName, Semantic semantic, ulong dataSource, ulong set)
        {
            ulong indPolylistInput = (ulong)DAEGeometry.ExpandInput(polylist);

            switch (semantic)
            {
            case Semantic.VERTEX:
                polylist.input[indPolylistInput] = new InputOffset("VERTEX", "#" + geoName + "-VERTEX", indPolylistInput);
                break;

            case Semantic.NORMAL:
                polylist.input[indPolylistInput] = new InputOffset("NORMAL", "#" + geoName + "-Normal" + dataSource, indPolylistInput);
                break;

            case Semantic.TEXCOORD:
                polylist.input[indPolylistInput] = new InputOffset("TEXCOORD", "#" + geoName + "-UV" + dataSource, indPolylistInput, set);
                break;

            case Semantic.COLOR:
                polylist.input[indPolylistInput] = new InputOffset("COLOR", "#" + geoName + "-VERTEX_COLOR" + dataSource, indPolylistInput, set);
                break;
            }
        }
示例#6
0
        public static Geometry Polylist(string geoID, string geoName, string matName, DAEGeometryDataSourceInfo[] dataSourceInfos, float[][] data, DAEGeometryInputSemanticInfo[] semanticsInfos, int[] vCount, int[] primitives)
        {
            int  maxLength = Math.Min((int)data.Length, (int)dataSourceInfos.Length);
            Mesh mesh      = new Mesh();

            mesh.source = new Source[0];
            Polylist polylist = new Polylist((ulong)vCount.Length, matName, vCount, primitives);

            polylist.input = new InputOffset[0];

            for (int i = 0; i < maxLength; i++)
            {
                DAEGeometry.AppendDataSource(mesh, geoName, dataSourceInfos[i].Type, data[i], dataSourceInfos[i].Index);
            }
            for (int i = 0; i < semanticsInfos.Length; i++)
            {
                DAEGeometry.AppendPolylistSemantic(polylist, geoName, semanticsInfos[i].Semantic, semanticsInfos[i].DataSourceIndex, semanticsInfos[i].SetIndex);
            }

            mesh.primitives = new object[] { polylist };
            Geometry geo = new Geometry(geoID, geoName, mesh);

            return(geo);
        }
示例#7
0
        private Geometry GetGeometry(ModelPart part, int i, string modelName)
        {
            var id = $"{modelName}-Part-{i}";

            var geometry = new Geometry
            {
                Name = id,
                Id   = id
            };

            var positions = GetSource("positions", part.Vertices, v => new float[] { v.Position.X, v.Position.Y, v.Position.Z });
            var normals   = GetSource("normals", part.Vertices, v => new float[] { v.Normal.X, v.Normal.Y, v.Normal.Z });
            var uv        = GetMapSource("map", part.Vertices, v => new float[] { v.U, v.V });

            var vertices = new Vertices()
            {
                Id = "vertices"
            };

            vertices.Input.Add(new InputLocal()
            {
                Semantic = "POSITION",
                Source   = "#positions"
            });

            var poly = new Polylist
            {
                Count    = (ulong)part.Faces.Count,
                Vcount   = string.Join(' ', Enumerable.Repeat(3, part.Faces.Count)),
                P        = string.Join(' ', part.Faces.SelectMany(f => new string[] { f.V1.ToString(), f.V2.ToString(), f.V3.ToString() })),
                Material = id + "-material"
            };

            poly.Input.Add(new InputLocalOffset()
            {
                Semantic = "VERTEX",
                Source   = "#vertices",
                Offset   = 0
            });

            poly.Input.Add(new InputLocalOffset()
            {
                Semantic = "NORMAL",
                Source   = "#normals",
                Offset   = 0
            });

            poly.Input.Add(new InputLocalOffset()
            {
                Semantic = "TEXCOORD",
                Source   = "#map",
                Offset   = 0
            });

            var mesh = new Mesh
            {
                Vertices = vertices
            };

            mesh.Source.Add(positions);
            mesh.Source.Add(normals);
            mesh.Source.Add(uv);
            mesh.Polylist.Add(poly);

            geometry.Mesh = mesh;

            return(geometry);
        }
        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;
                }
            }
        }