示例#1
0
    private Vector3 actualPolylineCenter;     //Polyline center to focus, for showGEneration=True

    void Start()
    {
        initialPoints           = new InitialPolyline(gateSize);
        pointsSelected          = 0;
        generatorCalled         = false;
        lines                   = new GameObject("Start Lines");
        actualPolylineDirection = Vector3.zero;
    }
    /**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);
    }
    /**Initializes the first stalagmite polyline and adds it to the mesh **/
    protected void initializeStalagmiteIni(ref Polyline stalgmPoly)
    {
        InitialPolyline actualStalagmiteIni = new InitialPolyline(stalgmPoly);

        for (int i = 0; i < stalgmPoly.getSize(); ++i)
        {
            actualStalagmiteIni.getVertex(i).setIndex(stalagmitesMeshes[stalagmitesMeshes.Count - 1].getNumVertices() + i);
        }
        stalgmPoly = actualStalagmiteIni;
        stalagmitesMeshes[stalagmitesMeshes.Count - 1].addPolyline(stalgmPoly);
    }
 /**Initialize, being the arguments the needed parameters for the generator **/
 public void initialize(int gateSize, InitialPolyline iniPol, float initialTunelHoleProb, int maxHoles, int maxExtrudeTimes)
 {
     showGeneration   = gameObject.GetComponent <CaveGenerator> ().showGeneration;
     smoothIterations = gameObject.GetComponent <CaveGenerator> ().smoothItIniTunel;
     for (int i = 0; i < smoothIterations; ++i)
     {
         iniPol.smoothMean();
     }
     iniPol.generateUVs();
     iniPol.duplicateFirstVertex();
     gatePolyline = iniPol;
     this.initialTunelHoleProb = initialTunelHoleProb;
     this.maxHoles             = maxHoles;
     this.maxExtrudeTimes      = maxExtrudeTimes;
     entranceSize = gateSize;
     if (entranceSize % 2 != 0)         //Force it to be pair
     {
         ++entranceSize;
     }
 }
示例#5
0
    /** Function to be called in order to start generating the cave **/
    public void startGeneration(InitialPolyline iniPol)
    {
        AbstractGenerator generator;

        //Start the generation
        switch (method)
        {
        case (generationMethod.Recursive): {
            generator = gameObject.AddComponent <RecursiveGenerator> ();
            break;
        }

        case (generationMethod.IterativeStack): {
            generator = gameObject.AddComponent <StackGenerator> ();

            break;
        }

        case (generationMethod.IterativeQueue): {
            generator = gameObject.AddComponent <QueueGenerator> ();
            break;
        }

        default:
            return;
        }

        float tunnelHoleProb = 0.8f;

        generator.initialize(gateSize, iniPol, tunnelHoleProb, maxHoles, maxExtrudeTimes);
        //Create the main game objects for meshes
        tunnelsList = new List <GameObject>();
        stalgmList  = new List <GameObject>();
        tunnels     = new GameObject("Tunnels");
        stalagmites = new GameObject("Stalagmites");

        //Use coroutines to show the generation steps
        StartCoroutine(generator.generate(iniPol, tunnelHoleProb));
    }
    /** 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);
    }