Esempio n. 1
0
        private static MeshLOD AdvancedToMesh(this ObjectPart.PrimitiveShape.Decoded shape)
        {
            ProfileDetails profile;

            switch (shape.ShapeType)
            {
            case PrimitiveShapeType.Ring:
                profile = CalcPrismProfile(shape);
                break;

            case PrimitiveShapeType.Torus:
                profile = CalcCylinderProfile(shape);
                break;

            case PrimitiveShapeType.Tube:
                profile = CalcBoxProfile(shape);
                break;

            case PrimitiveShapeType.Sphere:
                profile = CalcSphereProfile(shape);
                break;

            default:
                throw new NotImplementedException();
            }

            double cut         = shape.PathBegin;
            double cutBegin    = cut;
            double cutEnd      = shape.PathEnd;
            double cutStep     = (cutEnd - cut) / 36f / shape.Revolutions;
            double twistBegin  = shape.TwistBegin * Math.PI * 2;
            double twistEnd    = shape.TwistEnd * Math.PI * 2;
            double neededSteps = Math.Max(1, Math.Ceiling((shape.TwistEnd - shape.TwistBegin) / (5 * Math.PI / 180) * (cutEnd - cut)));

            cutStep /= neededSteps;

            var mesh = new MeshLOD();

            for (; cut < cutEnd; cut += cutStep)
            {
                mesh.Vertices.AddRange(profile.ExtrudeAdvanced(shape, twistBegin, twistEnd, cut));
            }
            mesh.Vertices.AddRange(profile.ExtrudeAdvanced(shape, twistBegin, twistEnd, cutEnd));

            shape.BuildAdvancedTriangles(mesh, profile, cutBegin, cutEnd);

            return(mesh);
        }
Esempio n. 2
0
        private static List <Vector3> ExtrudeBasic(this ProfileDetails path, ObjectPart.PrimitiveShape.Decoded shape, double twistBegin, double twistEnd, double cut)
        {
            var     extrusionPath = new List <Vector3>();
            double  twist;
            Vector3 topSize;
            Vector3 shear;

            CalcTopSizeAndShear(shape, twistBegin, twistEnd, cut, out topSize, out shear, out twist);

            /* generate extrusions */
            foreach (var vertex in path.Vertices)
            {
                var outvertex = vertex;
                outvertex.X *= topSize.X;
                outvertex.Y *= topSize.Y;
                outvertex    = outvertex.Rotate2D_XY(twist);
                outvertex   += shear;
                outvertex.Z  = cut - 0.5;
                extrusionPath.Add(outvertex);
            }
            return(extrusionPath);
        }
Esempio n. 3
0
        private static Vector3 CalcAdvVertex(this ObjectPart.PrimitiveShape.Decoded shape, Vector3 vertex, double angle, double twist, double cut, Vector3 taper, double radiusOffset)
        {
            double pathscale      = shape.PathScale.Y;
            double skew           = shape.Skew;
            double innerpathscale = pathscale - 0.5;

            var outvertex = vertex;

            outvertex.X *= taper.X;
            outvertex.Y *= taper.Y;
            outvertex    = outvertex.Rotate2D_XY(twist);

            outvertex.Z *= shape.PathScale.X;
            outvertex.Y *= 1 - Math.Abs(skew);
            outvertex.Y += skew * (1f - cut);

            outvertex.Y = innerpathscale.Lerp(0.5, outvertex.Y + 0.5) * radiusOffset;

            outvertex    = outvertex.Rotate2D_YZ(angle);
            outvertex.X += outvertex.Z * shape.TopShear.X;
            outvertex.Y += outvertex.Z * shape.TopShear.Y;
            return(outvertex);
        }
        public bool Run()
        {
            PhysicsShapeReference physicsShapeRef;
            bool success = true;

            foreach (PrimitiveShapeType shapeType in new PrimitiveShapeType[] { PrimitiveShapeType.Box, PrimitiveShapeType.Cylinder, PrimitiveShapeType.Prism, PrimitiveShapeType.Ring, PrimitiveShapeType.Sphere, PrimitiveShapeType.Torus, PrimitiveShapeType.Tube })
            {
                foreach (PrimitiveProfileShape profileShape in new PrimitiveProfileShape[] { PrimitiveProfileShape.Circle, PrimitiveProfileShape.EquilateralTriangle, PrimitiveProfileShape.HalfCircle, PrimitiveProfileShape.IsometricTriangle, PrimitiveProfileShape.RightTriangle, PrimitiveProfileShape.Square })
                {
                    foreach (PrimitiveProfileHollowShape hollowShape in new PrimitiveProfileHollowShape[] { PrimitiveProfileHollowShape.Circle, PrimitiveProfileHollowShape.Same, PrimitiveProfileHollowShape.Square, PrimitiveProfileHollowShape.Triangle })
                    {
                        foreach (PrimitivePhysicsShapeType physicsShapeType in new PrimitivePhysicsShapeType[] { PrimitivePhysicsShapeType.Convex, PrimitivePhysicsShapeType.Prim })
                        {
                            foreach (PrimitiveExtrusion pathCurve in new PrimitiveExtrusion[] { PrimitiveExtrusion.Curve1, PrimitiveExtrusion.Curve2, PrimitiveExtrusion.Default, PrimitiveExtrusion.Straight })
                            {
                                for (double pathbegin = 0; pathbegin < 1; pathbegin += 0.1)
                                {
                                    for (double pathend = 0; pathend < 1; pathend += 0.1)
                                    {
                                        for (double profilebegin = 0; profilebegin < 1; profilebegin += 0.1)
                                        {
                                            for (double profileend = 0; profileend < 1; profileend += 0.1)
                                            {
                                                for (double revolutions = 1; revolutions < 4; revolutions += 0.5)
                                                {
                                                    for (double twistbegin = -1; twistbegin < 1; twistbegin += 0.1)
                                                    {
                                                        for (double twistend = -1; twistend < 1; twistend += 0.1)
                                                        {
                                                            /*
                                                             * public double RadiusOffset;
                                                             */
                                                            for (double hollow = 0; hollow < 0.90; hollow += 0.1)
                                                            {
                                                                for (double skew = -0.9; skew < 0.9; skew += 0.1)
                                                                {
                                                                    for (double topshearx = -1; topshearx < 1; topshearx += 0.1)
                                                                    {
                                                                        for (double topsheary = -1; topsheary < 1; topsheary += 0.1)
                                                                        {
                                                                            for (double taperx = -1; taperx < 1; taperx += 0.1)
                                                                            {
                                                                                for (double tapery = -1; tapery < 1; tapery += 0.1)
                                                                                {
                                                                                    for (double pathscalex = 0; pathscalex < 1; pathscalex += 0.1)
                                                                                    {
                                                                                        for (double pathscaley = 0; pathscaley < 1; pathscaley += 0.1)
                                                                                        {
                                                                                            var shape = new ObjectPart.PrimitiveShape.Decoded();
                                                                                            shape.ProfileShape  = profileShape;
                                                                                            shape.ShapeType     = shapeType;
                                                                                            shape.HoleShape     = hollowShape;
                                                                                            shape.ProfileHollow = hollow;
                                                                                            shape.PathCurve     = pathCurve;
                                                                                            shape.Revolutions   = revolutions;
                                                                                            shape.PathBegin     = pathbegin;
                                                                                            shape.PathEnd       = pathend;
                                                                                            shape.TwistBegin    = twistbegin;
                                                                                            shape.TwistEnd      = twistend;
                                                                                            shape.ProfileBegin  = profilebegin;
                                                                                            shape.ProfileEnd    = profileend;
                                                                                            shape.TopShear.X    = topshearx;
                                                                                            shape.TopShear.Y    = topsheary;
                                                                                            shape.Taper.X       = taperx;
                                                                                            shape.Taper.Y       = tapery;
                                                                                            shape.PathScale.X   = pathscalex;
                                                                                            shape.PathScale.Y   = pathscaley;
                                                                                            shape.Skew          = skew;

                                                                                            var ps = new ObjectPart.PrimitiveShape
                                                                                            {
                                                                                                DecodedParams = shape
                                                                                            };

                                                                                            m_Log.Info("---- Transformed to physics shape manager accepted format ----");
                                                                                            m_Log.InfoFormat("PhysicsShapeType: {0}/{1}", physicsShapeType, shapeType);
                                                                                            m_Log.Info($"Serialized data {physicsShapeType.ToString()}/{ps.Serialization.ToHexString()}");
                                                                                            try
                                                                                            {
                                                                                                if (!m_PhysicsShapeManager.TryGetConvexShape(physicsShapeType, ps, out physicsShapeRef))
                                                                                                {
                                                                                                    DumpParams(shape);
                                                                                                    m_Log.Error("Could not generate physics hull shape");
                                                                                                    success = false;
                                                                                                    continue;
                                                                                                }
                                                                                            }
                                                                                            catch (Exception e)
                                                                                            {
                                                                                                DumpParams(shape);
                                                                                                m_Log.Error("Could not generate physics hull shape", e);
                                                                                                continue;
                                                                                            }

                                                                                            PhysicsConvexShape convexShape = physicsShapeRef;

                                                                                            int hullidx = 0;
                                                                                            foreach (PhysicsConvexShape.ConvexHull hull in convexShape.Hulls)
                                                                                            {
                                                                                                m_Log.InfoFormat("Hull {0}: Generated vertices: {1}", hullidx, hull.Vertices.Count);
                                                                                                m_Log.InfoFormat("Hull {0}: Generated triangles: {1}", hullidx, hull.Triangles.Count / 3);
                                                                                                ++hullidx;
                                                                                            }
                                                                                            m_Log.InfoFormat("Generated hulls: {0}", hullidx);
                                                                                        }
                                                                                    }
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                                /* write a blender .raw */
                                //                ((PhysicsConvexShape)physicsShapeRef).DumpToBlenderRaw(m_OutputFileName);
                            }
                        }
                    }
                }
            }

            return(success);
        }
        public void Startup(ConfigurationLoader loader)
        {
            IConfig config = loader.Config.Configs[GetType().FullName];

            m_AssetService        = loader.GetService <AssetServiceInterface>(config.GetString("AssetService", "AssetService"));
            m_PhysicsShapeManager = loader.GetService <PhysicsShapeManager>(config.GetString("PhysicsShapeManager", "PhysicsShapeManager"));

            string physicsShapeType = config.GetString("PhysicsShapeType", "prim").ToLowerInvariant();

            switch (physicsShapeType)
            {
            case "none":
                m_PhysicsShapeType = PrimitivePhysicsShapeType.None;
                break;

            case "prim":
                m_PhysicsShapeType = PrimitivePhysicsShapeType.Prim;
                break;

            case "convex":
                m_PhysicsShapeType = PrimitivePhysicsShapeType.Convex;
                break;

            default:
                throw new ConfigurationLoader.ConfigurationErrorException(string.Format("Invalid PhysicsShapeType: {0}", physicsShapeType));
            }

            if (config.Contains("HexData"))
            {
                ObjectPart.PrimitiveShape p = new ObjectPart.PrimitiveShape
                {
                    Serialization = config.GetString("HexData").FromHexStringToByteArray()
                };
                m_Shape = p.DecodedParams;
            }
            else
            {
                string shapeType = config.GetString("ShapeType", "Box").ToLowerInvariant();
                switch (shapeType)
                {
                case "box":
                    m_Shape.ShapeType = PrimitiveShapeType.Box;
                    break;

                case "cylinder":
                    m_Shape.ShapeType = PrimitiveShapeType.Cylinder;
                    break;

                case "prism":
                    m_Shape.ShapeType = PrimitiveShapeType.Prism;
                    break;

                case "sphere":
                    m_Shape.ShapeType = PrimitiveShapeType.Sphere;
                    break;

                case "torus":
                    m_Shape.ShapeType = PrimitiveShapeType.Torus;
                    break;

                case "tube":
                    m_Shape.ShapeType = PrimitiveShapeType.Tube;
                    break;

                case "ring":
                    m_Shape.ShapeType = PrimitiveShapeType.Ring;
                    break;

                case "sculpt":
                    m_Shape.ShapeType = PrimitiveShapeType.Sculpt;
                    break;

                default:
                    throw new ConfigurationLoader.ConfigurationErrorException(string.Format("Invalid ShapeType: {0}", shapeType));
                }

                string sculptType = config.GetString("SculptType", "sphere").ToLowerInvariant();
                switch (sculptType)
                {
                case "sphere":
                    m_Shape.SculptType = PrimitiveSculptType.Sphere;
                    break;

                case "torus":
                    m_Shape.SculptType = PrimitiveSculptType.Torus;
                    break;

                case "plane":
                    m_Shape.SculptType = PrimitiveSculptType.Plane;
                    break;

                case "cylinder":
                    m_Shape.SculptType = PrimitiveSculptType.Cylinder;
                    break;

                case "mesh":
                    m_Shape.SculptType = PrimitiveSculptType.Mesh;
                    break;

                default:
                    throw new ConfigurationLoader.ConfigurationErrorException(string.Format("Invalid SculptType: {0}", sculptType));
                }

                if (config.Contains("SculptMapID"))
                {
                    m_Shape.SculptMap = new UUID(config.GetString("SculptMapID"));
                }

                if (config.Contains("SculptMapFile"))
                {
                    if (!config.Contains("SculptMapID"))
                    {
                        throw new ConfigurationLoader.ConfigurationErrorException("SculptMap parameter not present");
                    }
                    byte[] data;
                    using (var fs = new FileStream(config.GetString("SculptMapFile"), FileMode.Open))
                    {
                        var fileLength = (int)fs.Length;
                        data = new byte[fileLength];
                        if (fileLength != fs.Read(data, 0, fileLength))
                        {
                            throw new ConfigurationLoader.ConfigurationErrorException("Failed to load file");
                        }
                    }
                    var assetdata = new AssetData
                    {
                        Data = data,
                        Type = m_Shape.SculptType == PrimitiveSculptType.Mesh ? AssetType.Mesh : AssetType.Texture,
                        ID   = m_Shape.SculptMap,
                        Name = "PrimToMesh imported"
                    };
                    m_AssetService.Store(assetdata);
                }

                if (config.GetBoolean("IsSculptInverted", false))
                {
                    m_Shape.IsSculptInverted = true;
                }
                if (config.GetBoolean("IsSculptMirrored", false))
                {
                    m_Shape.IsSculptMirrored = true;
                }

                string profileShape = config.GetString("ProfileShape", "Circle").ToLowerInvariant();
                switch (profileShape)
                {
                case "circle":
                    m_Shape.ProfileShape = PrimitiveProfileShape.Circle;
                    break;

                case "square":
                    m_Shape.ProfileShape = PrimitiveProfileShape.Square;
                    break;

                case "isometrictriangle":
                    m_Shape.ProfileShape = PrimitiveProfileShape.IsometricTriangle;
                    break;

                case "equilateraltriangle":
                    m_Shape.ProfileShape = PrimitiveProfileShape.EquilateralTriangle;
                    break;

                case "righttriangle":
                    m_Shape.ProfileShape = PrimitiveProfileShape.RightTriangle;
                    break;

                case "halfcircle":
                    m_Shape.ProfileShape = PrimitiveProfileShape.HalfCircle;
                    break;

                default:
                    throw new ConfigurationLoader.ConfigurationErrorException(string.Format("Invalid ProfileShape: {0}", profileShape));
                }

                string holeShape = config.GetString("HollowShape", "Same").ToLowerInvariant();
                switch (holeShape)
                {
                case "same":
                    m_Shape.HoleShape = PrimitiveProfileHollowShape.Same;
                    break;

                case "circle":
                    m_Shape.HoleShape = PrimitiveProfileHollowShape.Circle;
                    break;

                case "square":
                    m_Shape.HoleShape = PrimitiveProfileHollowShape.Square;
                    break;

                case "triangle":
                    m_Shape.HoleShape = PrimitiveProfileHollowShape.Triangle;
                    break;

                default:
                    throw new ConfigurationLoader.ConfigurationErrorException(string.Format("Invalid HollowShape: {0}", holeShape));
                }

                m_Shape.ProfileBegin  = double.Parse(config.GetString("ProfileBegin", "0"), CultureInfo.InvariantCulture);
                m_Shape.ProfileEnd    = double.Parse(config.GetString("ProfileEnd", "1"), CultureInfo.InvariantCulture);
                m_Shape.ProfileHollow = double.Parse(config.GetString("ProfileHollow", "0"), CultureInfo.InvariantCulture);
                m_Shape.IsHollow      = m_Shape.ProfileHollow > 0;
                m_Shape.PathBegin     = double.Parse(config.GetString("PathBegin", "0"), CultureInfo.InvariantCulture);
                m_Shape.PathEnd       = double.Parse(config.GetString("PathEnd", "1"), CultureInfo.InvariantCulture);
                m_Shape.IsOpen        = m_Shape.ProfileBegin > 0 || m_Shape.ProfileEnd < 1f;
                m_Shape.PathScale.X   = double.Parse(config.GetString("PathScaleX", "0"), CultureInfo.InvariantCulture);
                m_Shape.PathScale.Y   = double.Parse(config.GetString("PathScaleY", "0"), CultureInfo.InvariantCulture);
                m_Shape.TopShear.X    = double.Parse(config.GetString("TopShearX", "0"), CultureInfo.InvariantCulture);
                m_Shape.TopShear.Y    = double.Parse(config.GetString("TopShearY", "0"), CultureInfo.InvariantCulture);
                m_Shape.TwistBegin    = double.Parse(config.GetString("TwistBegin", "0"), CultureInfo.InvariantCulture);
                m_Shape.TwistEnd      = double.Parse(config.GetString("TwistEnd", "0"), CultureInfo.InvariantCulture);
                m_Shape.RadiusOffset  = double.Parse(config.GetString("RadiusOffset", "0"), CultureInfo.InvariantCulture);
                m_Shape.Taper.X       = double.Parse(config.GetString("TaperX", "0"), CultureInfo.InvariantCulture);
                m_Shape.Taper.Y       = double.Parse(config.GetString("TaperY", "0"), CultureInfo.InvariantCulture);
                m_Shape.Revolutions   = double.Parse(config.GetString("Revolutions", "1"), CultureInfo.InvariantCulture);
                m_Shape.Skew          = double.Parse(config.GetString("Skew", "0"), CultureInfo.InvariantCulture);
            }

            m_OutputFileName = config.GetString("OutputFilename");
        }
Esempio n. 6
0
        private static ProfileDetails CalcPrismProfile(this ObjectPart.PrimitiveShape.Decoded shape)
        {
            /* Prism has cut start at 0,0.5 */
            var profile = new ProfileDetails();

            double startangle = 2 * Math.PI * shape.ProfileBegin;
            double endangle   = 2 * Math.PI * shape.ProfileEnd;
            double stepangle  = (endangle - startangle) / 60;
            var    angles     = shape.CalcBaseAngles(startangle, endangle, stepangle);

            if (shape.IsHollow)
            {
                /* we calculate two points */
                double  profileHollow = shape.ProfileHollow * 0.5;
                Vector3 startPoint    = Vector3.UnitX * 0.5;
                foreach (var angle in angles)
                {
                    Vector3 outerDirectionalVec = CalcTrianglePoint(angle);
                    Vector3 innerDirectionalVec;

                    switch (shape.HoleShape)
                    {
                    case PrimitiveProfileHollowShape.Triangle:
                    case PrimitiveProfileHollowShape.Same:
                        innerDirectionalVec = outerDirectionalVec * profileHollow;
                        break;

                    case PrimitiveProfileHollowShape.Circle:
                        /* circle is simple as we are calculating with such objects */
                        innerDirectionalVec = startPoint.Rotate2D_XY(angle) * profileHollow;
                        break;

                    case PrimitiveProfileHollowShape.Square:
                        innerDirectionalVec = CalcTopEdgedSquare(angle) * profileHollow;
                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    /* inner path is reversed */
                    profile.Vertices.Add(outerDirectionalVec);
                    profile.Vertices.Insert(0, innerDirectionalVec);
                }
                /* no center point here, even though we can have path cut */
                profile.IsOpenHollow = shape.IsOpen;
            }
            else
            {
                /* no hollow, so it becomes simple */
                foreach (var angle in angles)
                {
                    Vector3 directionalVec = CalcTrianglePoint(angle);
                    profile.Vertices.Add(directionalVec);
                }
                if (shape.IsOpen)
                {
                    profile.Vertices.Add(new Vector3(0, 0, 0));
                }
                else
                {
                    profile.Vertices.RemoveAt(profile.Vertices.Count - 1);
                }
            }

            return(profile);
        }
Esempio n. 7
0
        private static ProfileDetails CalcBoxProfile(this ObjectPart.PrimitiveShape.Decoded shape)
        {
            /* Box has cut start at 0.5,-0.5 */
            var profile = new ProfileDetails();

            double        startangle = 2 * Math.PI * shape.ProfileBegin;
            double        endangle   = 2 * Math.PI * shape.ProfileEnd;
            double        stepangle  = (endangle - startangle) / 60;
            List <double> angles     = shape.CalcBaseAngles(startangle, endangle, stepangle);

            if (shape.IsHollow)
            {
                /* we calculate two points */
                Vector3 startPoint = START_VECTOR_BOX * 0.5;
                foreach (var angle in angles)
                {
                    Vector3 outerDirectionalVec = startPoint.Rotate2D_XY(angle);
                    Vector3 innerDirectionalVec = outerDirectionalVec;

                    /* outer normalize on single component to 0.5, simplifies algorithm */
                    outerDirectionalVec = outerDirectionalVec.CalcPointToSquareBoundary(1);

                    switch (shape.HoleShape)
                    {
                    case PrimitiveProfileHollowShape.Triangle:
                        innerDirectionalVec = CalcTrianglePoint(angle).Rotate2D_XY(-2.3561944901923448) * shape.ProfileHollow * 0.5;
                        break;

                    case PrimitiveProfileHollowShape.Circle:
                        /* circle is simple as we are calculating with such objects */
                        innerDirectionalVec *= shape.ProfileHollow;
                        break;

                    case PrimitiveProfileHollowShape.Same:
                    case PrimitiveProfileHollowShape.Square:
                        /* inner normalize on single component to 0.5 * hollow */
                        innerDirectionalVec = innerDirectionalVec.CalcPointToSquareBoundary(shape.ProfileHollow);
                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    /* inner path is reversed */
                    profile.Vertices.Add(outerDirectionalVec);
                    profile.Vertices.Insert(0, innerDirectionalVec);
                }
                /* no center point here, even though we can have path cut */
                profile.IsOpenHollow = shape.IsOpen;
            }
            else
            {
                /* no hollow, so it becomes simple */
                Vector3 startPoint = START_VECTOR_BOX * 0.5;
                foreach (var angle in angles)
                {
                    Vector3 directionalVec = startPoint.Rotate2D_XY(angle);
                    /* normalize on single component to 0.5, simplifies algorithm */
                    directionalVec = directionalVec.CalcPointToSquareBoundary(1);
                    profile.Vertices.Add(directionalVec);
                }
                if (shape.IsOpen)
                {
                    profile.Vertices.Add(new Vector3(0, 0, 0));
                }
                else
                {
                    profile.Vertices.RemoveAt(profile.Vertices.Count - 1);
                }
            }

            return(profile);
        }
Esempio n. 8
0
        private static void BuildBasicTriangles(this ObjectPart.PrimitiveShape.Decoded shape, MeshLOD mesh, ProfileDetails path, double cutBegin, double cutEnd)
        {
            double twistBegin         = shape.TwistBegin * Math.PI;
            double twistEnd           = shape.TwistEnd * Math.PI;
            int    verticeRowCount    = path.Vertices.Count;
            int    verticeTotalCount  = mesh.Vertices.Count;
            int    verticeRowEndCount = verticeRowCount;

            if (!shape.IsOpen && shape.IsHollow)
            {
                --verticeRowEndCount;
            }

            /* generate z-triangles */
            for (int l = 0; l < verticeRowEndCount; ++l)
            {
                if (!shape.IsOpen && shape.IsHollow && l == verticeRowCount / 2 - 1)
                {
                    continue;
                }
                for (int z = 0; z < verticeTotalCount - verticeRowCount; z += verticeRowCount)
                {
                    /* p0  ___  p1 */
                    /*    |   |    */
                    /*    |___|    */
                    /* p3       p2 */
                    /* tris: p0, p1, p2 and p0, p3, p2 */
                    /* p2 and p3 are on next row */
                    int z2  = z + verticeRowCount;
                    int l2  = (l + 1) % verticeRowCount; /* loop closure */
                    var tri = new Triangle
                    {
                        Vertex1 = z + l,
                        Vertex2 = z2 + l2,
                        Vertex3 = z + l2
                    };
                    mesh.Triangles.Add(tri);

                    tri = new Triangle
                    {
                        Vertex1 = z + l,
                        Vertex2 = z2 + l,
                        Vertex3 = z2 + l2
                    };
                    mesh.Triangles.Add(tri);
                }
            }

            /* generate top and bottom triangles */
            if (shape.IsHollow)
            {
                /* simpler just close neighboring dots */

                /* no need for uneven check here.
                 * The path generator always generates two pathes here which are connected and therefore always a multiple of two */
                int bottomIndex = verticeTotalCount - verticeRowCount;
                for (int l = 0; l < verticeRowCount / 2; ++l)
                {
                    int l2 = verticeRowCount - l - 1;

                    var tri = new Triangle
                    {
                        Vertex1 = l,
                        Vertex2 = l2,
                        Vertex3 = l + 1
                    };
                    mesh.Triangles.Add(tri);

                    tri = new Triangle
                    {
                        Vertex1 = l + 1,
                        Vertex2 = l2,
                        Vertex3 = l2 - 1
                    };
                    mesh.Triangles.Add(tri);

                    tri = new Triangle
                    {
                        Vertex1 = l + bottomIndex,
                        Vertex2 = l2 + bottomIndex,
                        Vertex3 = l + 1 + bottomIndex
                    };
                    mesh.Triangles.Add(tri);

                    tri = new Triangle
                    {
                        Vertex1 = l + 1 + bottomIndex,
                        Vertex2 = l2 + bottomIndex,
                        Vertex3 = l2 - 1 + bottomIndex
                    };
                    mesh.Triangles.Add(tri);
                }
            }
            else
            {
                /* build a center point and connect all vertexes with triangles */
                int centerpointTop = mesh.Vertices.Count;
                int bottomIndex    = verticeTotalCount - verticeRowCount;
                mesh.Vertices.Add(ApplyTortureParams(shape, new Vector3(0, 0, 0), twistBegin, twistEnd, cutBegin));
                int centerpointBottom = mesh.Vertices.Count;
                mesh.Vertices.Add(ApplyTortureParams(shape, new Vector3(0, 0, 0), twistBegin, twistEnd, cutEnd));
                for (int l = 0; l < verticeRowCount; ++l)
                {
                    int l2 = (l + 1) % verticeRowCount;

                    var tri = new Triangle
                    {
                        Vertex1 = l,
                        Vertex2 = l2,
                        Vertex3 = centerpointTop
                    };
                    mesh.Triangles.Add(tri);

                    tri = new Triangle
                    {
                        Vertex1 = l + bottomIndex,
                        Vertex2 = l2 + bottomIndex,
                        Vertex3 = centerpointBottom
                    };
                    mesh.Triangles.Add(tri);
                }
            }
        }
Esempio n. 9
0
        private static ProfileDetails CalcSphereProfile(this ObjectPart.PrimitiveShape.Decoded shape)
        {
            /* calculate a half-sphere here
             * starting from UnitX to -UnitX
             */
            var profile = new ProfileDetails();

            double startangle = Math.PI * shape.ProfileBegin;
            double endangle   = Math.PI * shape.ProfileEnd;
            double stepangle  = (endangle - startangle) / 60;

            if (shape.IsHollow)
            {
                /* we calculate two points */
                Vector3 startPoint = Vector3.UnitX * 0.5;
                for (; startangle < endangle; startangle += stepangle)
                {
                    Vector3 outerDirectionalVec = startPoint.Rotate2D_XY(startangle);
                    Vector3 innerDirectionalVec;

                    switch (shape.HoleShape)
                    {
                    case PrimitiveProfileHollowShape.Triangle:
                        /* Even though, the option is called Triangle. It is actually a Trapezoid. */
                        innerDirectionalVec = CalcTrapezoidInSpherePoint(startangle) * (shape.ProfileHollow * 0.5);
                        break;

                    case PrimitiveProfileHollowShape.Same:
                    case PrimitiveProfileHollowShape.Circle:
                        /* circle is simple as we are calculating with such objects */
                        innerDirectionalVec = CalcTrianglePoint(startangle) * shape.ProfileHollow;
                        break;

                    case PrimitiveProfileHollowShape.Square:
                        innerDirectionalVec = CalcSquareInSpherePoint(startangle) * (shape.ProfileHollow * 0.5);
                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    /* inner path is reversed */
                    profile.Vertices.Add(outerDirectionalVec);
                    profile.Vertices.Insert(0, innerDirectionalVec);
                }
                /* no center point here, even though we can have path cut */
                profile.IsOpenHollow = shape.IsOpen;
            }
            else
            {
                /* no hollow, so it becomes simple */
                Vector3 startPoint = Vector3.UnitX * 0.5;
                for (; startangle < endangle; startangle += stepangle)
                {
                    Vector3 directionalVec = startPoint.Rotate2D_XY(startangle);
                    profile.Vertices.Add(directionalVec);
                }
                if (shape.IsOpen)
                {
                    profile.Vertices.Add(new Vector3(0, 0, 0));
                }
            }

            return(profile);
        }
Esempio n. 10
0
        internal static MeshLOD SculptMeshToMesh(this Bitmap bitmap, ObjectPart.PrimitiveShape.Decoded shape, bool generate_uv = false)
        {
            bool mirror                    = shape.IsSculptMirrored;
            var  mesh                      = new MeshLOD();
            bool reverse_horizontal        = shape.IsSculptInverted ? !mirror : mirror;
            PrimitiveSculptType sculptType = shape.SculptType;

            int sculptSizeS;
            int sculptSizeT;
            int sculptVerts = bitmap.Width * bitmap.Height / 4;

            if (sculptVerts > 32 * 32)
            {
                sculptVerts = 32 * 32;
            }
            double ratio = (double)bitmap.Width / bitmap.Height;

            sculptSizeS = (int)Math.Sqrt(sculptVerts / ratio);

            sculptSizeS = Math.Max(sculptSizeS, 4);
            sculptSizeT = sculptVerts / sculptSizeS;

            sculptSizeT = Math.Max(sculptSizeT, 4);
            sculptSizeS = sculptVerts / sculptSizeT;

            /* generate vertex map */
            for (int s = 0; s < sculptSizeS; ++s)
            {
                for (int t = 0; t < sculptSizeT; ++t)
                {
                    int reversed_t = t;
                    if (reverse_horizontal)
                    {
                        reversed_t = sculptSizeT - t - 1;
                    }
                    var x = (int)((double)reversed_t / (sculptSizeT - 1) * bitmap.Width);
                    var y = (int)((double)s / (sculptSizeS - 1) * bitmap.Height);

                    if (y == 0)
                    {
                        if (sculptType == PrimitiveSculptType.Sphere)
                        {
                            x = bitmap.Width / 2;
                        }
                    }
                    else if (y == bitmap.Height)
                    {
                        y = (sculptType == PrimitiveSculptType.Torus) ?
                            0 :
                            bitmap.Height - 1;

                        if (sculptType == PrimitiveSculptType.Sphere)
                        {
                            x = bitmap.Width / 2;
                        }
                    }

                    if (x == bitmap.Width)
                    {
                        switch (sculptType)
                        {
                        case PrimitiveSculptType.Sphere:
                        case PrimitiveSculptType.Torus:
                        case PrimitiveSculptType.Cylinder:
                            x = 0;
                            break;

                        default:
                            x = bitmap.Width - 1;
                            break;
                        }
                    }

                    Vector3 v = bitmap.GetVertex(x, y, mirror);
                    mesh.Vertices.Add(v);
                    if (generate_uv)
                    {
                        var uv = new UVCoord
                        {
                            U = (float)reversed_t / (sculptSizeS - t),
                            V = (float)s / (sculptSizeS - 1)
                        };
                        mesh.UVCoords.Add(uv);
                    }
                }
            }

            /* generate triangles */
            for (int row = 0; row < sculptSizeS - 1; ++row)
            {
                int rowIndex  = row * sculptSizeT;
                int row2Index = rowIndex + sculptSizeT;
                for (int col = 0; col < sculptSizeT - 1; ++col)
                {
                    var tri = new Triangle
                    {
                        Vertex1 = rowIndex + col,
                        Vertex2 = row2Index + col + 1,
                        Vertex3 = rowIndex + col + 1
                    };
                    mesh.Triangles.Add(tri);

                    tri = new Triangle
                    {
                        Vertex1 = rowIndex + col,
                        Vertex2 = row2Index + col,
                        Vertex3 = row2Index + col + 1
                    };
                    mesh.Triangles.Add(tri);
                }
            }

            return(mesh);
        }