Example #1
0
            public static bool Connected(GroupedFaceUV a, GroupedFaceUV b)
            {
                float dot = Vector3.Dot(a.Normal, b.Normal);
                if (dot < DOT_THRESHOLD) // non-coplanar faces
                    return false;

                int commonEdgeCnt = 0;

                for (int i = 0; i < 3; ++i)
                {
                    VtxHash ae0 = a.vtxHash[e0LUT[i]];
                    VtxHash ae1 = a.vtxHash[e1LUT[i]];

                    for (int j = 0; j < 3; ++j)
                    {
                        VtxHash be0 = b.vtxHash[e0LUT[j]];
                        VtxHash be1 = b.vtxHash[e1LUT[j]];

                        if(	(ae0.Equals(be0) && ae1.Equals(be1))
                        ||	(ae0.Equals(be1) && ae1.Equals(be0)))
                            ++commonEdgeCnt;
                    }
                }

                return commonEdgeCnt > 0;
            }
Example #2
0
        public override List<Mesh> Unwrap(Mesh mesh, int packSize, float worldScale)
        {
            List<GroupedFaceUV> faceuvs = new List<GroupedFaceUV>();

            BeginEvent();

            int fcnt = mesh.FaceCount;
            for (int i = 0; i < fcnt; ++i)
            {
                Vector3 p0, p1, p2, e1, e2;

                // computer the face normal
                mesh.Positions.GetFace(out p0, out p1, out p2, i);

                e1 = p1 - p0; e1.Normalize();
                e2 = p2 - p0; e2.Normalize();

                Vector3 n = Vector3.Cross(e1, e2);
                n.Normalize();

                // get major axis & assign texcoord
                TC tc = GetMajorAxis(ref n);

                GroupedFaceUV fuv = new GroupedFaceUV();
                fuv.Texcrd[0] = tc(p0, worldScale);
                fuv.Texcrd[1] = tc(p1, worldScale);
                fuv.Texcrd[2] = tc(p2, worldScale);
                fuv.Normal = n;
                fuv.ComputeVtxHash(p0, p1, p2, Precision);

                faceuvs.Add(fuv);
            }

            EndEvent("Generate faceuvs");

            // group the faces
            BeginEvent();

            int gCnt = CreateGroups(faceuvs);

            Console.WriteLine("{0} faces created {1} groups", fcnt, gCnt);

            List<Group> groups = new List<Group>();

            EndEvent("Group faceuvs");

            // packing
            BeginEvent();

            PackSettings packSettings = new PackSettings();
            List<PackOutputList> packOutputs = new List<PackOutputList>();
            List<PackInput> packInputs = new List<PackInput>();

            for (int i = 0; i < gCnt; ++i)
            {
                Group gp = new Group();
                gp.Count = GroupedFaceUV.Bounding(out gp.Min, out gp.Max, faceuvs, i);
                groups.Add(gp);

                PackInput pi = new PackInput();
                pi.Size.Width = (int)Math.Ceiling(gp.Max.X - gp.Min.X);
                pi.Size.Height = (int)Math.Ceiling(gp.Max.Y - gp.Min.Y);
                packInputs.Add(pi);

                if (debug)
                {
                    Console.Write("gp{0}: ", i);
                    GroupedFaceUV.Dump(faceuvs, i);
                }
            }

            EndEvent("Prepare pack inputs");

            BeginEvent();

            bool ok = false;

            do
            {
                packSettings.Size.Width = packSize;
                packSettings.Size.Height = packSize;
                packSettings.Border = Border;

                packOutputs.Clear();

                JimScottPacker packer = new JimScottPacker();
                packer.debug = debug;
                packer.Pack(packSettings, packInputs, packOutputs);

                if (SingleMeshOutput)
                {
                    ok = packOutputs.Count == 1;
                    if (!ok) packSize = packSize * 2;
                }

            } while (SingleMeshOutput && !ok);

            EndEvent("Packing");

            BeginEvent();

            Vector2 scale = new Vector2(1.0f / packSize, 1.0f / packSize);

            // convert pack outputs back to faceuv
            foreach (PackOutputList polist in packOutputs)
            {
                foreach (PackOutput po in polist)
                {
                    Group gp = groups[po.Input];

                    foreach (GroupedFaceUV fuv in faceuvs)
                    {
                        if (fuv.GroupId != po.Input) continue;

                        fuv.Translate(new Vector2(po.X, po.Y) - gp.Min);
                        fuv.Scale(scale);
                    }
                }
            }

            // create output meshes
            List<Mesh> output = new List<Mesh>();

            foreach (PackOutputList polist in packOutputs)
            {
                Mesh omesh = new Mesh();

                int ofcnt = 0;
                for (int i = 0; i < polist.Count; ++i)
                    ofcnt += groups[polist[i].Input].Count;

                omesh.Init(ofcnt * 3);

                int dst = 0;

                for (int i = 0; i < polist.Count; ++i)
                {
                    for (int src = 0; src < fcnt; ++src)
                    {
                        GroupedFaceUV fuv = faceuvs[src];

                        if (fuv.GroupId != polist[i].Input) continue;

                        mesh.Positions.CopyFaceTo(omesh.Positions, src, dst);
                        mesh.Normals.CopyFaceTo(omesh.Normals, src, dst);
                        mesh.Texcrds0.CopyFaceTo(omesh.Texcrds0, src, dst);

                        omesh.Texcrds1.SetFace(dst, fuv.Texcrd[0], fuv.Texcrd[1], fuv.Texcrd[2]);

                        if(debug)
                            omesh.FaceProps[dst] = src;
                        else
                            omesh.FaceProps[dst] = mesh.FaceProps[src];

                        ++dst;
                    }
                }
                output.Add(omesh);
            }

            OutputSize = packSize;

            EndEvent("Prepare pack outputs");

            return output;
        }