예제 #1
0
    /**From two extrusion polylines, get the polylines that are the start of a stalgmite, with the nearest objective direction **/
    protected Polyline[] getStalagmiteIni(int numStalgm, int stalgmSize, Polyline originPoly, Polyline newPoly, Vector3 objective)
    {
        InitialPolyline[] result     = new InitialPolyline[numStalgm];
        List <int>        startIndex = new List <int>(); //Indices of the first vertices used for each polyline

        for (int p = 0; p < numStalgm; ++p)
        {
            InitialPolyline stalgmPoly  = new InitialPolyline(stalgmSize);
            float           stalgmAngle = float.MaxValue;
            float           auxAngle;
            int             finalIndex = -1;
            for (int i = 0; i < originPoly.getSize() - 1; ++i)
            {
                bool invalidIndex = false;
                int  aux          = 0;
                //Check it's vertices don't intersect with any of the stalgmites of the same extrusion
                for (int j = 0; j < startIndex.Count && !invalidIndex; ++j)
                {
                    aux = startIndex [j];
                    //Check i is not any of the vertices corresponding to jth estalgmite
                    invalidIndex = (i >= aux && i < aux + stalgmSize / 2 - 1) || (aux >= i && aux < i + stalgmSize / 2 - 1);
                }
                if (invalidIndex)
                {
                    i = aux + stalgmSize / 2 - 1;                 //Jump the next index not corresponding to the intersected stalagmite
                    continue;
                }
                //Construct the stalgmite polyline
                InitialPolyline auxPoly = new InitialPolyline(stalgmSize);
                for (int j = (stalgmSize / 2) - 1; j >= 0; --j)
                {
                    auxPoly.addVertex(originPoly.getVertex(i + j));
                }
                for (int j = 0; j < (stalgmSize / 2); ++j)
                {
                    auxPoly.addVertex(newPoly.getVertex(i + j));
                }
                auxAngle = Vector3.Angle(auxPoly.calculateNormal(), objective);
                //Get the one with minimum angle
                if (auxAngle < stalgmAngle)
                {
                    stalgmPoly  = auxPoly;
                    stalgmAngle = auxAngle;
                    finalIndex  = i;
                }
            }
            //Add obtained polyline avoid intersection with another one on same extrusion
            startIndex.Add(finalIndex);
            //If angle with objective direction is very high, cancel its creation
            if (stalgmAngle > maxDiffAngle)
            {
                stalgmPoly = null;
            }
            //Add stalgmite initial polyline to result
            result[p] = stalgmPoly;
        }
        return(result);
    }
예제 #2
0
    /** Makes a hole betwen two polylines and return this hole as a new polyline **/
    protected Polyline makeHole(Polyline originPoly, Polyline destinyPoly)
    {
        //TODO: more than one hole, Make two holes on same polylines pairs can cause intersections!
        //could take the negate direction of the already make hole and try to do a new one

        // FIRST: Decide where the hole will be done, take advantatge indices
        // on the two polylines are at the same order (the new is kind of a projection of the old)
        int sizeHole; int firstIndex;

        //DecisionGenerator.Instance.whereToDig (originPoly.getSize(), out sizeHole, out firstIndex);
        DecisionGenerator.Instance.whereToDig(originPoly, out sizeHole, out firstIndex);
        if (sizeHole < DecisionGenerator.Instance.holeMinVertices)
        {
            return(null);
        }
        //SECOND: Create the hole polyline by marking and adding the hole vertices (from old a new polylines)
        InitialPolyline polyHole = new InitialPolyline(sizeHole);
        //Increasing order for the origin and decreasing for the destiny polyline in order to
        //make a correct triangulation
        int i = 0;

        while (i < sizeHole / 2)
        {
            originPoly.getVertex(firstIndex + i).setInHole(true);
            polyHole.addVertex(originPoly.getVertex(firstIndex + i));
            ++i;
        }
        //at this point i = sizeHole / 2;
        while (i > 0)
        {
            --i;
            destinyPoly.getVertex(firstIndex + i).setInHole(true);
            polyHole.addVertex(destinyPoly.getVertex(firstIndex + i));
        }

        /*//THIRD: Check is a valid hole: no artifacts will be produced,
         * bool invalidHole = false;
         * //invalidHole = Geometry.Utils.checkArtifacts (polyHole);
         * //and in the walking case, check if the hole is not too upwards or downwards(y component)
         * //invalidHole = invalidHole || Geometry.Utils.checkInvalidWalk(polyHole);
         * //Undo hole if invalid
         * if (invalidHole) {
         *      Debug.Log ("Invalid walk");
         *      for (int j = 0; j < sizeHole/2; ++j) {
         *              originPoly.getVertex (firstIndex + j).setInHole (false);
         *              destinyPoly.getVertex (firstIndex + j).setInHole (false);
         *      }
         *      return null;
         * }*/

        //FOURTH: Do the hole smooth: Project the polyline(3D) into a plane(2D) on the polyline normal direction, just n (not very big) vertices
        InitialPolyline planePoly = Geometry.Utils.generateProjection(polyHole, entranceSize, smoothIterations);

        //FIFTH: Last check if hole is really valid (intersection stuff, convex polyline and not too small check)
        if (planePoly.computeMinimumRadius() < planePoly.getMinRadius() || !planePoly.isConvex() || IntersectionsController.Instance.doIntersect(polyHole, planePoly, -1))
        {
            /*if (!planePoly.isConvex ())
            *       Debug.Log ("Not Convex");
            *  else
            *       Debug.Log ("Intersection");*/
            for (int j = 0; j < sizeHole / 2; ++j)
            {
                originPoly.getVertex(firstIndex + j).setInHole(false);
                destinyPoly.getVertex(firstIndex + j).setInHole(false);
            }
            return(null);
        }
        //In case the hole can really be done, add the extruded polyline to the mesh
        // (needed for triangulate correctly between the hole and the projection)
        actualMesh.addPolyline(destinyPoly);
        //And the corresponding hole vertices
        for (int j = 0; j < polyHole.getSize(); ++j)
        {
            actualMesh.addHoleIndex(polyHole.getVertex(j).getIndex());
        }

        //SIXTH: Final propoerties of the projection
        //Generate new UVs coordinates of the projection, from y coord of the hole (not works very well)
        float yCoord = (polyHole.getVertex(0).getUV().y + polyHole.getVertex(-1).getUV().y) / 2;

        planePoly.generateUVs(yCoord);
        //Duplicate the first vertex in order to have good texturization between last and first vertex
        planePoly.duplicateFirstVertex();
        //And put the corresponding indices
        for (int j = 0; j < planePoly.getSize(); ++j)
        {
            planePoly.getVertex(j).setIndex(actualMesh.getNumVertices() + j);
        }
        //Add the new polyline information to the mesh
        actualMesh.addPolyline(planePoly);

        ///FINALLY: Triangulate between the hole and the projection and add the projection to the B intersections
        actualMesh.triangulateTunnelStart(polyHole, planePoly);
        IntersectionsController.Instance.addPolyline(planePoly);

        return(planePoly);
    }