예제 #1
0
    public void Subdivide(Polygon _polygon)
    {
        //_polygon = _polygon.GetMirrorX();
        _subdividedPolygon.Clear ();
        _curveIndices.Clear ();
        _indexedAngleType.Clear ();

        // boundingBox de l'element de margelle correspondant a l'angle 90°
        //Bounds rightAngleRimBounds = new Bounds (new Vector3 (-0.085f, 0.025f, -0.085f) * 100, new Vector3 (0.45f, 0.05f, 0.45f) * 100);
        //Bounds rightAngleRimBounds = new Bounds (new Vector3 (-0.15f, 0.00005f, -0.15f)*100, new Vector3 (0.3f, 0.0001f, 0.3f)*100);
        Bounds rightAngleRimBounds = new Bounds (new Vector3 (-0.13f, 1.0f, -0.13f) * 100, new Vector3 (0.30f, 1.0f, 0.30f)*100);
        //Bounds rightAngleRimBounds = new Bounds (new Vector3 (-0.075f, 0.00005f, -0.075f) * 100, new Vector3 (0.15f, 0.05f, 0.15f)*100);

        // longueur des coupures a realiser avant et apres les points d'angle 90°
        float xCutOffset = rightAngleRimBounds.center.x + rightAngleRimBounds.extents.x;
        float zCutOffset = rightAngleRimBounds.center.z + rightAngleRimBounds.extents.z;

        int ptIndices = 0;

        // pour chaque point
        //_polygon.UpdateBounds();
        //Bounds polyBounds = _polygon.bounds;
        foreach (Point2 currentPoint in _polygon.GetPoints ())
        {
            //Point2 currentPoint = (Point2) currentPoint2.Clone();
            //Point2 currentPoint = currentPoint2.;
            //currentPoint.SetX(currentPoint2.GetX()*1);
            //currentPoint.SetX(2*polyBounds.center.x + currentPoint.GetX());
            if (currentPoint.GetJunction () == JunctionType.Broken)
            {
                // si c'est un angle de 90°
                if (Utils.Approximately (currentPoint.GetAngle (), 90) && currentPoint.GetAngleType () == AngleType.Outside)
                {
                    float xCut = xCutOffset;
                    float zCut = zCutOffset;
                    //Debug.Log("xCutOffset : "+xCutOffset);
                    //Debug.Log("zCutOffset : "+zCutOffset);

                    AngleType angleType = currentPoint.GetAngleType ();

        //				if (angleType == AngleType.Inside)
        //				{
        //					xCut = rightAngleRimBounds.size.x;
        //					zCut = rightAngleRimBounds.size.z;
        //				}

                    // si angle exterieur
                    if (angleType == AngleType.Inside)
                    {
                        ptIndices++;
                        _subdividedPolygon.Add (currentPoint);
                    }

                    // si angle interieur
                    if (angleType == AngleType.Outside)
                    {
                        // On coupe avant et apres le point sur les segments precedent et suivant
                        // de longueur xCut et zCut respectivement
                        Vector2 prevDirection = currentPoint.GetPrevEdge ().ToVector2 ().normalized * -1;
                        Vector2 prevPoint = currentPoint + prevDirection * xCut;

                        Vector2 nextDirection = currentPoint.GetNextEdge ().ToVector2 ().normalized;
                        Vector2 nextPoint = currentPoint + nextDirection * zCut;

                        ptIndices++;
                        _subdividedPolygon.Add (prevPoint);
                        ptIndices++;
                        _subdividedPolygon.Add (currentPoint);
                        ptIndices++;
                        _subdividedPolygon.Add (nextPoint);
                    }

                }
                else
                {
                    // pour les angle non predefini
                    AngleType angleType = currentPoint.GetAngleType ();

                    float rimWidth = 0.31f * 100; // largeur de la margelle
                    float sectionLength = rimWidth * currentPoint.GetNormalScaleFactor ();
                    float outsideLength = Mathf.Sqrt (sectionLength * sectionLength - rimWidth * rimWidth);
                    float subdividedLimit = RIM_SIZE;// + RIM_SIZE / 2;

                    // si angle exterieur
                    if (angleType == AngleType.Inside)
                    {
                        Edge2 prevEdge = currentPoint.GetPrevEdge ();

                        if (prevEdge != null && _subdividedPolygon.Count > 0)
                        {
                            // verification si le point tangent et le point correspondant a la futur coupure sont a fusionner
                            // si oui pas de coupure
                            bool merged = false;
                            ArchedPoint2 prevAPoint = prevEdge.GetPrevPoint2 () as ArchedPoint2;

                            if (prevAPoint != null && prevAPoint.IsNextTangentPointMerged ())
                            {
                                merged = true;
                            }

                            if (!merged)
                            {
                                // on cree la coupure sur le segment precedent le point courant en fonction de la longueur
                                // de la margelle coté plage (exterieur car angle interieur)
                                Vector2 prevSubdVector = _subdividedPolygon[_subdividedPolygon.Count - 1];
                                float prevEdgeLength = Vector2.Distance (currentPoint, prevSubdVector);

                                if (prevEdgeLength > subdividedLimit)
                                {
                                    if (outsideLength >= RIM_SIZE - MIN_INSIDE_RIM_LENGTH)
                                    {
                                        Vector2 prevDirection = prevEdge.ToVector2 ().normalized * -1;
                                        Vector2 prevPoint = currentPoint + prevDirection * (outsideLength + MIN_INSIDE_RIM_LENGTH);

                                        ptIndices++;
                                        _subdividedPolygon.Add (prevPoint);
                                    }
                                    else
                                    {
                                        Vector2 prevDirection = prevEdge.ToVector2 ().normalized * -1;
                                        Vector2 prevPoint = currentPoint + prevDirection * RIM_SIZE;

                                        ptIndices++;
                                        _subdividedPolygon.Add (prevPoint);
                                    }
                                }
                            }
                        }

                        ptIndices++;
                        _subdividedPolygon.Add (currentPoint);	// ajout du point courant

                        Edge2 nextEdge = currentPoint.GetNextEdge ();

                        // meme procedure pour la coupure sur le segment suivant le point courant
                        if (nextEdge != null && nextEdge.GetLength () > subdividedLimit)
                        {
                            bool merged = false;
                            ArchedPoint2 nextAPoint = nextEdge.GetNextPoint2 () as ArchedPoint2;

                            if (nextAPoint != null && nextAPoint.IsPrevTangentPointMerged ())
                            {
                                merged = true;
                            }

                            if (!merged)
                            {
                                if (outsideLength >= RIM_SIZE - MIN_INSIDE_RIM_LENGTH)
                                {
                                    Vector2 nextDirection = nextEdge.ToVector2 ().normalized;
                            //		nextDirection.y*=-1;
                                    Vector2 nextPoint = currentPoint + nextDirection * (outsideLength + MIN_INSIDE_RIM_LENGTH);

                                    ptIndices++;
                                    _subdividedPolygon.Add (nextPoint);
                                }
                                else
                                {
                                    Vector2 nextDirection = nextEdge.ToVector2 ().normalized;
                            //		nextDirection.y*=-1;
                                    Vector2 nextPoint = currentPoint + nextDirection * RIM_SIZE;

                                    ptIndices++;
                                    _subdividedPolygon.Add (nextPoint);
                                }
                            }
                        }
                    }

                    // si angle interieur
                    // meme procedure que precedemment mais en prenant comme reference la longueur de margelle
                    // cote liner (longueur interieur car angle exterieur)
                    if (angleType == AngleType.Outside)
                    {
                        Edge2 prevEdge = currentPoint.GetPrevEdge ();

                        if (prevEdge != null && _subdividedPolygon.Count > 0)
                        {
                            bool merged = false;
                            ArchedPoint2 prevAPoint = prevEdge.GetPrevPoint2 () as ArchedPoint2;

                            if (prevAPoint != null && prevAPoint.IsNextTangentPointMerged ())
                            {
                                merged = true;
                            }

                            if (!merged)
                            {
                                Vector2 prevSubdVector = _subdividedPolygon[_subdividedPolygon.Count - 1];
                                float prevEdgeLength = Vector2.Distance (currentPoint, prevSubdVector);

                                if (prevEdgeLength > subdividedLimit)
                                {
                                    if (outsideLength <= RIM_SIZE - MIN_INSIDE_RIM_LENGTH)
                                    {
                                        float length = RIM_SIZE - outsideLength;
                                        Vector2 prevDirection = prevEdge.ToVector2 ().normalized * -1;
                                        Vector2 prevPoint = currentPoint + prevDirection * length;

                                        ptIndices++;
                                        _subdividedPolygon.Add (prevPoint);
                                    }
                                    else
                                    {
                                        Vector2 prevDirection = prevEdge.ToVector2 ().normalized * -1;
                                    //	prevDirection.y*=-1;
                                        Vector2 prevPoint = currentPoint + prevDirection * MIN_INSIDE_RIM_LENGTH;

                                        ptIndices++;
                                        _subdividedPolygon.Add (prevPoint);
                                    }
                                }
                            }
                        }

                        ptIndices++;
                        _subdividedPolygon.Add (currentPoint);

                        Edge2 nextEdge = currentPoint.GetNextEdge ();

                        if (nextEdge != null && nextEdge.GetLength () > subdividedLimit)
                        {
                            bool merged = false;
                            ArchedPoint2 nextAPoint = nextEdge.GetNextPoint2 () as ArchedPoint2;

                            if (nextAPoint != null && nextAPoint.IsPrevTangentPointMerged ())
                            {
                                merged = true;
                            }

                            if (!merged)
                            {
                                if (outsideLength <= RIM_SIZE - MIN_INSIDE_RIM_LENGTH)
                                {
                                    float length = RIM_SIZE - outsideLength;
                                    Vector2 nextDirection = nextEdge.ToVector2 ().normalized;
                                    Vector2 nextPoint = currentPoint + nextDirection * length;

                                    ptIndices++;
                                    _subdividedPolygon.Add (nextPoint);
                                }
                                else
                                {
                                    Vector2 nextDirection = nextEdge.ToVector2 ().normalized;

                            //		nextDirection.y*=-1;
                                    Vector2 nextPoint = currentPoint + nextDirection * MIN_INSIDE_RIM_LENGTH;

                                    ptIndices++;
                                    _subdividedPolygon.Add (nextPoint);
                                }
                            }
                        }
                    }
                }
            }
            else if (currentPoint.GetJunction () == JunctionType.Curved)
            {
                // si on est dans un arc de cercle pas de subdivision a effectuer
                // on ajoute chaque point de l'arc de cercle
                ArchedPoint2 ar = currentPoint as ArchedPoint2;

                int startCurveIndex = _subdividedPolygon.Count;

                // ajout de l'indice du premier point de l'arc de cercle
                // pour le mapping dans PolygonLofter
                _curveIndices.Add (startCurveIndex);

                // on associe l'indice de debut de courbe au type d'angle courant
                _indexedAngleType.Add (startCurveIndex, currentPoint.GetAngleType ());

                foreach (Vector2 p in ar.GetCurve ())
                {
                    ptIndices++;
                    _subdividedPolygon.Add (p);
                }

                int endCurveIndex = _subdividedPolygon.Count - 1;

                // ajout de l'indice du dernier point de l'arc de cercle
                // pour le mapping dans PolygonLofter
                _curveIndices.Add (endCurveIndex);
            }
        }

        // decoupage au niveau du point 0 et du segment precedent le point 0
        // meme procedure que precedemment
        Point2 firstPoint = _polygon.GetPoints ()[0];
        Edge2 firstPrevEdge = firstPoint.GetPrevEdge ();

        if (firstPrevEdge != null && firstPoint.GetJunction () == JunctionType.Broken)
        {
            float rimWidth = 0.31f * 100;
            float sectionLength = rimWidth * firstPoint.GetNormalScaleFactor ();
            float outsideLength = Mathf.Sqrt (sectionLength * sectionLength - rimWidth * rimWidth);
            float subdividedLimit = RIM_SIZE; //+ RIM_SIZE / 2;

            if (firstPoint.GetAngleType () == AngleType.Inside)
            {
                Vector2 prevSubdVector = _subdividedPolygon[_subdividedPolygon.Count - 1];
                float prevEdgeLength = Vector2.Distance (firstPoint, prevSubdVector);

                if (prevEdgeLength > subdividedLimit)
                {
                    if (outsideLength >= RIM_SIZE - MIN_INSIDE_RIM_LENGTH)
                    {
                        Vector2 prevDirection = firstPrevEdge.ToVector2 ().normalized * -1;
                        Vector2 prevPoint = firstPoint + prevDirection * (outsideLength + MIN_INSIDE_RIM_LENGTH);

                        ptIndices++;
                        _subdividedPolygon.Add (prevPoint);
                    }
                    else
                    {
                        Vector2 prevDirection = firstPrevEdge.ToVector2 ().normalized * -1;
                        Vector2 prevPoint = firstPoint + prevDirection * RIM_SIZE;

                        ptIndices++;
                        _subdividedPolygon.Add (prevPoint);
                    }
                }
            }

            if (firstPoint.GetAngleType () == AngleType.Outside && !Utils.Approximately (firstPoint.GetAngle (), 90))
            {
                Vector2 prevSubdVector = _subdividedPolygon[_subdividedPolygon.Count - 1];
                float prevEdgeLength = Vector2.Distance (firstPoint, prevSubdVector);

                if (prevEdgeLength > subdividedLimit)
                {
                    if (outsideLength <= RIM_SIZE - MIN_INSIDE_RIM_LENGTH)
                    {
                        float length = RIM_SIZE - outsideLength;
                        Vector2 prevDirection = firstPrevEdge.ToVector2 ().normalized * -1;
                        Vector2 prevPoint = firstPoint + prevDirection * length;

                        ptIndices++;
                        _subdividedPolygon.Add (prevPoint);
                    }
                    else
                    {
                        Vector2 prevDirection = firstPrevEdge.ToVector2 ().normalized * -1;
                        Vector2 prevPoint = firstPoint + prevDirection * MIN_INSIDE_RIM_LENGTH;

                        ptIndices++;
                        _subdividedPolygon.Add (prevPoint);
                    }
                }
            }
        }

        // on exprime le polygone subdivisé en coordonnées monde, avec son repere centré sur son centre
        Vector2 translation = _polygon.GetPolygonCenter () * -1;

        for (int ptIndex = 0; ptIndex < _subdividedPolygon.Count; ++ptIndex)
        {
            _subdividedPolygon[ptIndex] = (_subdividedPolygon[ptIndex] + translation) * _polygonScaleFactor;
        }
    }
예제 #2
0
    public void Generate(Polygon _polygon)
    {
        //_polygon = new Polygon(_polygon.GenerateWithCurveInverse());
        // On genere les meshs des composants de la piscine

        if (_polygon.GetPoints ().Count < 3)
            return;

        if (!_polygon.IsClosed ())
        {
            _polygon.Close ();
        }

        _polygon = _polygon.GetMirrorX();

        _polygon.UpdateBounds ();
        Vector2 translation = _polygon.GetPolygonCenter () * -1;
        Vector2 mirror = new Vector2(1,-1);
        // exprime le polygone en coordonnées monde, avec son repere centré sur son centre
        PolygonRawData polyRaw = new PolygonRawData ();
        foreach (Vector2 pt in _polygon.GenerateWithCurve ())
        //foreach (Vector2 pt in _polygon.GenerateWithCurveInverse ())
        //PolygonRawData polydata = _polygon.GenerateWithCurveInverse ();
        //polydata.Reverse();
        //foreach (Vector2 pt in polydata)
        {
            Vector2 transformedPt = (pt + translation) * _polygonScaleFactor;
            /*Vector2 newpt = new Vector2();
            newpt.x=pt.x;
            newpt.y=pt.y;

            newpt.y = 2*_polygon.bounds.center.z - newpt.y;
            Vector2 transformedPt = (newpt + translation) * _polygonScaleFactor;*/
            polyRaw.Add (transformedPt);
        }

        _transformedPolygon = new Polygon (polyRaw);

        // generate liner
        Mesh linerMesh = _liner.GetComponent<MeshFilter> ().mesh;
        PolygonExtruder linerExtrusion = new PolygonExtruder (_transformedPolygon, linerMesh, -1.5f, false, true, true);
        linerExtrusion.Generate ();

        LinerScatteringMapper lsm = new LinerScatteringMapper (linerMesh);
        lsm.Generate ();

        PolygonExtruderMapper pem = new PolygonExtruderMapper (linerExtrusion);
        pem.Generate ();

        // generate sidewalk
        Mesh sidewalkMesh = _sidewalk.GetComponent<MeshFilter> ().mesh;
        SideWalkExtruder se = new SideWalkExtruder (_transformedPolygon, sidewalkMesh, -0.02f, 2);
        se.Generate ();

        PlannarMapper pm = new PlannarMapper (sidewalkMesh, Vector3.up);
        pm.Generate ();

        // generate rim
        _rimGenerator.Generate (_polygon);

        // generate occlusion
        PolygonRawData occluShape = new PolygonRawData ();
        occluShape.Add (new Vector2 (0.28f, 0));
        occluShape.Add (new Vector2 (0.33f, 0));

        Polygon occluProfile = new Polygon (occluShape);
        occluProfile.SetClosed (false);

        Mesh occluMesh = _occlusion.GetComponent<MeshFilter> ().mesh;
        PolygonLofter occluLofter = new PolygonLofter (_transformedPolygon, occluProfile, occluMesh);
        _occlusion.GetComponent<Renderer>().enabled = false;
        occluLofter.Generate ();

        // generate water
        Mesh waterMesh = _water.GetComponent<MeshFilter> ().mesh;
        PolygonExtruder waterPlan = new PolygonExtruder (_transformedPolygon, waterMesh, 0, true, false, false);
        waterPlan.Generate ();

        PlannarMapper waterMapper = new PlannarMapper (waterMesh, Vector3.down, UVChannel.uv0, 5);
        waterMapper.Generate ();

        // generate frieze
        Mesh friezeMesh = _frieze.GetComponent<MeshFilter> ().mesh;
        PolygonExtruder friezeExtrusion = new PolygonExtruder (_transformedPolygon, friezeMesh, -0.10f, false, false, true);
        friezeExtrusion.Generate ();

        PolygonExtruderMapper friezeMapper = new PolygonExtruderMapper (friezeExtrusion);
        friezeMapper.Generate ();

        LinerScatteringMapper lsmFrieze = new LinerScatteringMapper (friezeMesh);
        lsmFrieze.Generate ();

        // generate mask
        Mesh maskMesh = _mask.GetComponent<MeshFilter> ().mesh;
        PolygonExtruder maskExtrusion = new PolygonExtruder (_transformedPolygon, maskMesh, -0.10f, false, false, true);
        maskExtrusion.Generate ();

        PolygonExtruderMapper maskMapper = new PolygonExtruderMapper (maskExtrusion);
        maskMapper.Generate ();

        // generate collision mesh
        Mesh collisionMesh = new Mesh ();
        collisionMesh.name = "collision";

        Polygon collisionPoly = PolygonOperation.GetOutlinedPolygon (_transformedPolygon, 0.33f);
        PolygonExtruder collisionExtruder = new PolygonExtruder(collisionPoly, collisionMesh, 0.07f, true, false, false);
        collisionExtruder.Generate ();

        _meshCollider.sharedMesh = collisionMesh;
        _meshCollider.convex = true;
        collisionMesh.RecalculateBounds ();

        // on ajoute le mesh de collision au renderer parent de la margelle
        // pour le calcul de la boundingBox lié a la fonction de redimensionnement
        // de la plage.
        _rim.gameObject.GetComponent<MeshFilter> ().mesh = collisionMesh;
    }