Ejemplo n.º 1
0
    // fusion de la forme de base (liner, margelle) et rectangle exterieur
    // pour la triangulation
    // voir http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
    protected void MergedInnerAndOuter()
    {
        Bounds polyBounds = _polygon.bounds;
        Vector3 extents = polyBounds.extents;
        Vector3 center = polyBounds.center;

        // Pythagore
        float translation = _outlineOffset * 1.41421356f; // sqrt (2)

        Vector2 upRightDir = new Vector2 (1, 1).normalized * translation;
        Vector2 upRight = new Vector2 (center.x + extents.x, center.z + extents.z) + upRightDir;

        Vector2 downRightDir = new Vector2 (1, -1).normalized * translation;
        Vector2 downRight = new Vector2 (center.x + extents.x, center.z - extents.z) + downRightDir;

        Vector2 downLeftDir = new Vector2 (-1, -1).normalized * translation;
        Vector2 downLeft = new Vector2 (center.x - extents.x, center.z - extents.z) + downLeftDir;

        Vector2 upLeftDir = new Vector2 (-1, 1).normalized * translation;
        Vector2 upLeft = new Vector2 (center.x - extents.x, center.z + extents.z) + upLeftDir;

        PolygonRawData outerRawPoly = new PolygonRawData ();
        outerRawPoly.Add (upRight);
        outerRawPoly.Add (downRight);
        outerRawPoly.Add (downLeft);
        outerRawPoly.Add (upLeft);

        Polygon outerPolygon = new Polygon (outerRawPoly);
        _mergedPolygon = PolygonOperation.MergeInnerAndOuter (_polygon, outerPolygon);
    }
Ejemplo n.º 2
0
    // fusionne deux polygones. Inner doit etre totalement inclus dans outer
    // permet la triangulation d'un polygonr avec un trou --> plage
    // voir http://www.geometrictools.com/Documentation/TriangulationByEarClipping.pdf
    public static MergedPolygon MergeInnerAndOuter(Polygon inner, Polygon outer)
    {
        MergedPolygon mergedPolygon = new MergedPolygon ();
        PolygonRawData mergedPolyRaw = new PolygonRawData ();

        MutuallyVisibleVertices mvv = FindMutuallyVisibleVertices (inner, outer);

        LoopedList<Point2> innerPoints = inner.GetPoints ();
        LoopedList<Point2> outerPoints = outer.GetPoints ();

        int innerIndex = 0;
        for (; innerIndex <= mvv.innerIndex; ++innerIndex)
        {
            mergedPolyRaw.Add (innerPoints[innerIndex]);
        }

        mergedPolygon.originalIndex0 = mergedPolyRaw.Count - 1;
        mergedPolygon.originalIndex1 = mergedPolyRaw.Count;

        for (int counter = 0, outerIndex = mvv.outerIndex;
            counter < outerPoints.Count;
            ++counter, --outerIndex)
        {
            mergedPolyRaw.Add (outerPoints[outerIndex]);
        }

        mergedPolyRaw.Add (outerPoints[mvv.outerIndex] + mvv.duplicatedMVVOffset);
        mergedPolygon.duplicatedIndex1 = mergedPolyRaw.Count - 1;

        mergedPolyRaw.Add (innerPoints[mvv.innerIndex] + mvv.duplicatedMVVOffset);
        mergedPolygon.duplicatedIndex0 = mergedPolyRaw.Count - 1;

        for (; innerIndex < innerPoints.Count; ++innerIndex)
        {
            mergedPolyRaw.Add (innerPoints[innerIndex]);
        }

        mergedPolygon.polygonRawData = mergedPolyRaw;

        //		Debug.Log (mergedPolygon.originalIndex0 + " " + mergedPolygon.originalIndex1 + " " + mergedPolygon.duplicatedIndex0 + " " + mergedPolygon.duplicatedIndex1);

        return mergedPolygon;
    }
Ejemplo n.º 3
0
    // genere un ensemble de points correspondant au polygone avec ses avec arc de cercle
    public PolygonRawData GenerateWithCurveInverse()
    {
        PolygonRawData curvedPolygon = new PolygonRawData ();
        float minX = 0.0f;
        float maxX = 0.0f;
        float median=0.0f;
        foreach (Point2 point in _points)
        {
            if(point.GetX()>maxX)
                maxX=point.GetX();
            if(point.GetX()<minX)
                minX=point.GetX();
        }
        median = (maxX+minX)/2.0f;

        foreach (Point2 point in _points)
        //for (int i=_points.Count-1; i>=0; i--)
        {
        //	Point2 point = _points[i];
            float decalage = median - point.GetX();
            float newX = median + decalage;
            point.Set(
                newX,
                point.GetY()
                );
            /*point.Set(
                point.GetX(),
                point.GetY()
                );*/
            if (point.GetJunction () == JunctionType.Broken)
            {
                curvedPolygon.Add (point);
            }
            else if (point.GetJunction () == JunctionType.Curved)
            {
                ArchedPoint2 ar = point as ArchedPoint2;

                foreach (Vector2 v in ar.GetCurve ())
                {
                    curvedPolygon.Add (v);
                }
            }
        }

        return curvedPolygon;
    }
Ejemplo n.º 4
0
    // retourne l'arc de cercle sous forme d'une liste de point
    // voir ArcDrawer pour l'algo
    public PolygonRawData GetCurve()
    {
        PolygonRawData rawCurve = new PolygonRawData ();

        Vector2 firstPoint2Add = _prevTangentPoint;
        Vector2 lastPoint2Add = _nextTangentPoint;

        Vector2 startVector = (_prevTangentPoint - _center).normalized;
        Vector2 endVector = (_nextTangentPoint - _center).normalized;

        Vector2 angleMeasureReference = Vector2.right;

        if (_angleType == AngleType.Outside)
        {
            startVector = (_nextTangentPoint - _center).normalized;
            endVector = (_prevTangentPoint - _center).normalized;

            firstPoint2Add = _nextTangentPoint;
            lastPoint2Add = _prevTangentPoint;
        }

        float startAngle;
        if (Utils.Approximately (Vector3.Cross (startVector, angleMeasureReference).z, 0))
        {
            startAngle = Vector2.Dot (startVector, angleMeasureReference) < 0 ? 180 : 0;
        }
        else
        {
            Quaternion startRotation = Quaternion.FromToRotation (angleMeasureReference, startVector);
            startAngle = startRotation.eulerAngles.z;
        }

        float endAngle;
        if (Utils.Approximately (Vector3.Cross (endVector, angleMeasureReference).z, 0))
        {
            endAngle = Vector2.Dot (endVector, angleMeasureReference) < 0 ? 180 : 0;
        }
        else
        {
            Quaternion endRotation = Quaternion.FromToRotation (angleMeasureReference, endVector);
            endAngle = endRotation.eulerAngles.z;
        }

        // round angle
        startAngle = Mathf.Round(startAngle * 100) / 100;
        endAngle = Mathf.Round(endAngle * 100) / 100;

        //Debug.Log (startAngle + " " + endAngle);

        if (startAngle > endAngle)
        {
            endAngle += 360;
        }

        startAngle += ANGLE_STEP;
        float currentAngle = startAngle;

        rawCurve.Add (firstPoint2Add);

        while (currentAngle < endAngle)
        {
            float radAngle = currentAngle * Mathf.Deg2Rad;
            Vector2 arcPoint = new Vector2 (Mathf.Cos (radAngle), Mathf.Sin (radAngle)) * _measuredRadius + _center;

            if (_angleType == AngleType.Outside)
            {
                rawCurve.Insert (0, arcPoint);
            }
            else
            {
                rawCurve.Add (arcPoint);
            }

            currentAngle += ANGLE_STEP;
        }

        if (_angleType == AngleType.Outside)
        {
            rawCurve.Insert (0, lastPoint2Add);
        }
        else
        {
            rawCurve.Add (lastPoint2Add);
        }

        //		if (_prevTangentPointMerged)
        //		{
        //			rawCurve.RemoveAt (0);
        //		}
        //
        //		if (_nextTangentPointMerged)
        //		{
        //			rawCurve.RemoveAt (rawCurve.Count - 1);
        //		}

        return rawCurve;
    }
Ejemplo n.º 5
0
    public void Generate(Polygon _polygon)
    {
        _rimParts.Clear ();
        _rimLofters.Clear ();
        _corners.Clear ();

        foreach (Transform child in _rim.transform)
        {
            GameObject.Destroy (child.gameObject);
        }

        _rars.Subdivide (_polygon);
        Polygon subdividedPolygon = new Polygon (_rars.GetSubdividedPolygon ());
        subdividedPolygon.SetClosed (_polygon.IsClosed ());

        //******************* OBTENTION DU PROFILE A EXTERNALISER ********************//
        PolygonRawData shapeRaw = new PolygonRawData ();

        /*shapeRaw.Add (new Vector2 (0, 0));
        shapeRaw.Add (new Vector2 (0, 0.01f));
        shapeRaw.Add (new Vector2 (-0.015f, 0.026f));
        shapeRaw.Add (new Vector2 (-0.015f, 0.042f));
        shapeRaw.Add (new Vector2 (-0.006f, 0.06f));
        shapeRaw.Add (new Vector2 (0.01f, 0.069f));
        shapeRaw.Add (new Vector2 (0.03f, 0.071f));
        shapeRaw.Add (new Vector2 (0.049f, 0.066f));
        shapeRaw.Add (new Vector2 (0.071f, 0.06f));

        shapeRaw.Add (new Vector2 (0.1f, 0.052f));
        shapeRaw.Add (new Vector2 (0.169f, 0.044f));
        shapeRaw.Add (new Vector2 (0.249f, 0.041f));
        shapeRaw.Add (new Vector2 (0.29f, 0.04f));
        shapeRaw.Add (new Vector2 (0.298f, 0.038f));
        shapeRaw.Add (new Vector2 (0.305f, 0.033f));
        shapeRaw.Add (new Vector2 (0.309f, 0.024f));
        shapeRaw.Add (new Vector2 (0.31f, 0.014f));
        shapeRaw.Add (new Vector2 (0.31f, 0));*/

        shapeRaw.Add (new Vector2 (-0.02f, 0.0f));
        shapeRaw.Add (new Vector2 (0.28f, 0.0f));
        shapeRaw.Add (new Vector2 (0.28f, 0.001f));
        shapeRaw.Add (new Vector2 (-0.02f, 0.001f));

        Polygon profile = new Polygon (shapeRaw);
        profile.SetClosed (false);
        //************************************************************************//

        Polygon currentPortion = null;
        bool inPortion = false;
        bool inCurve = false;

        int pointCounter = 0;
        int indexOffset = 0;

        // pour chaque point du polygon subdivisé
        // si c'est un angle prédéfini on charge le mesh margelle associé
        // sinon on crée un section avec l'outil loft jusqu'au prochain angle prédéfini
        foreach (Point2 currentPoint in subdividedPolygon.GetPoints ())
        {
            float angle = currentPoint.GetAngle ();
            AngleType angleType = currentPoint.GetAngleType ();

            if (inPortion || inCurve)
            {
                Point2 pointToAdd = new Point2 (currentPoint);
                currentPortion.AddPoint (pointToAdd);
            }

            Edge2 nextEdge = currentPoint.GetNextEdge ();
            Edge2 prevEdge = currentPoint.GetPrevEdge ();
            Point2 nextPoint = null;
            Point2 prevPoint = null;

            if (nextEdge != null)
            {
                nextPoint = nextEdge.GetNextPoint2 ();
                prevPoint = prevEdge.GetPrevPoint2 ();

                float nextAngle = nextPoint.GetAngle ();
                AngleType nextAngleType = nextPoint.GetAngleType ();
                // stop case for onr portion
                if (Utils.Approximately (nextAngle, 90) && inPortion && nextAngleType == AngleType.Outside)
                {
                    inPortion = false;
                    currentPortion.SetClosed (false);

                    GameObject portionGO = new GameObject ("portion");
                    portionGO.transform.parent = _rim.transform;
                    portionGO.transform.localPosition = Vector3.zero;
                    portionGO.transform.localRotation = Quaternion.identity;
                    portionGO.transform.localScale = Vector3.one;

                    portionGO.AddComponent<MeshRenderer> ();
                    MeshFilter meshFilter = portionGO.AddComponent<MeshFilter> ();

                    PolygonLofter polyLofter = new PolygonLofter (currentPortion, profile, meshFilter.mesh);
                    polyLofter.SetCurveIndices (_rars.GetCurveIndices ());
                    polyLofter.SetIndexedAngleType (_rars.GetIndexedAngleType ());

                    polyLofter.SetIndexOffset (indexOffset + 1, subdividedPolygon.GetPoints ().Count);
                    polyLofter.Generate ();

                    portionGO.GetComponent<Renderer>().material = _portionMaterial;

                    _rimParts.Add (currentPortion);
                    _rimLofters.Add (polyLofter);
                }

                // angle prédéfini (90°) --> piece a charger
                if (Utils.Approximately (angle, 90) && angleType == AngleType.Outside)
                {
                    _corners.Add (currentPoint);

                    Vector3 angleRimPosition = new Vector3 (currentPoint.GetX (),
                                                            0,
                                                            currentPoint.GetY ());

                    Vector2 nextEdgeDirection = currentPoint.GetNextEdge ().ToVector2 ();
                    Vector3 toDirection = new Vector3 (nextEdgeDirection.x, 0, nextEdgeDirection.y);
                    Quaternion angleRimOrientation = Quaternion.LookRotation (toDirection);

                    GameObject rimCorner = Object.Instantiate (Resources.Load ("PoolDesigner/rimCorner")) as GameObject;

                    rimCorner.transform.parent = _rim.transform;
                    rimCorner.transform.localPosition = angleRimPosition;
                    rimCorner.transform.localRotation = angleRimOrientation;
                    rimCorner.transform.localScale = Vector3.one;

                    //rimCorner.transform.GetChild (0).GetChild (1).renderer.material = _portionMaterial;
                    rimCorner.transform.GetChild (0).GetChild (0).GetComponent<Renderer>().material = _portionMaterial;

                    if (!inPortion)
                    {
                        inPortion = true;
                        indexOffset = pointCounter;
                        currentPortion = new Polygon ();
                    }
                }

            /*	if (Utils.Approximately (nextAngle, 90) && (currentPoint.GetX()==nextPoint.GetX()) && (currentPoint.GetY()==nextPoint.GetY())
                    && (currentPoint.GetX()==prevPoint.GetX()) && (currentPoint.GetY()==prevPoint.GetY()))
                {
                    _corners.Add (currentPoint);

                    Vector3 angleRimPosition = new Vector3 (currentPoint.GetX (),
                                                            0,
                                                            currentPoint.GetY ());

                    Vector2 nextEdgeDirection = nextPoint.GetNextEdge ().ToVector2();
                    Vector3 toDirection = new Vector3 (nextEdgeDirection.x, 0, nextEdgeDirection.y);
                    Quaternion angleRimOrientation = Quaternion.LookRotation (toDirection);

                    GameObject rimCorner = Object.Instantiate (Resources.Load ("PoolDesigner/rimCorner")) as GameObject;

                    rimCorner.transform.parent = _rim.transform;
                    rimCorner.transform.localPosition = angleRimPosition;
                    rimCorner.transform.localRotation = angleRimOrientation;
                    rimCorner.transform.localScale = Vector3.one;

                    //rimCorner.transform.GetChild (0).GetChild (1).renderer.material = _portionMaterial;
                    rimCorner.transform.GetChild (0).GetChild (0).renderer.material = _portionMaterial;

                    if (!inPortion)
                    {
                        inPortion = true;
                        indexOffset = pointCounter;
                        currentPortion = new Polygon ();
                    }

                }*/

            }

            ++pointCounter;
        }

        if (inPortion) // si on etait entrain d'ajouter des points a une portion
        {
            if (_polygon.IsClosed ()) // on ajoute les points restants
            {
                inPortion = false;

                Point2 currentPoint = subdividedPolygon.GetPoints ()[0];
                float angle = currentPoint.GetAngle ();
                AngleType angleType = currentPoint.GetAngleType ();

                while (!Utils.Approximately (angle, 90) || angleType == AngleType.Inside)
                {
                    Point2 pointToAdd = new Point2 (currentPoint);
                    currentPortion.AddPoint (pointToAdd);

                    currentPoint = currentPoint.GetNextEdge ().GetNextPoint2 ();
                    angle = currentPoint.GetAngle ();
                    angleType = currentPoint.GetAngleType ();
                }
            }

            GameObject portionGO = new GameObject ("portion");
            portionGO.transform.parent = _rim.transform;
            portionGO.transform.localPosition = Vector3.zero;
            portionGO.transform.localRotation = Quaternion.identity;
            portionGO.transform.localScale = Vector3.one;

            portionGO.AddComponent<MeshRenderer> ();
            MeshFilter meshFilter = portionGO.AddComponent<MeshFilter> ();

            PolygonLofter polyLofter = new PolygonLofter (currentPortion, profile, meshFilter.mesh);

            polyLofter.SetIndexOffset (indexOffset + 1, subdividedPolygon.GetPoints ().Count);
            polyLofter.SetCurveIndices (_rars.GetCurveIndices ());
            polyLofter.SetIndexedAngleType (_rars.GetIndexedAngleType ());
            polyLofter.Generate ();

            portionGO.GetComponent<Renderer>().material = _portionMaterial;

            _rimParts.Add (currentPortion);
            _rimLofters.Add (polyLofter);
        }

        // Cas ou il n'y a pas de d'angle predefini
        // une seule portion qui correspond au polygone subdivise
        if (_corners.Count == 0)
        {
            GameObject portionGO = new GameObject ("portion");
            portionGO.transform.parent = _rim.transform;
            portionGO.transform.localPosition = Vector3.zero;
            portionGO.transform.localRotation = Quaternion.identity;
            portionGO.transform.localScale = Vector3.one;

            portionGO.AddComponent<MeshRenderer> ();
            MeshFilter meshFilter = portionGO.AddComponent<MeshFilter> ();

            PolygonLofter polyLofter = new PolygonLofter (subdividedPolygon, profile, meshFilter.mesh);
            polyLofter.SetIndexOffset (0, subdividedPolygon.GetPoints ().Count);
            polyLofter.SetCurveIndices (_rars.GetCurveIndices ());
            polyLofter.SetIndexedAngleType (_rars.GetIndexedAngleType ());
            polyLofter.Generate ();

            portionGO.GetComponent<Renderer>().material = _portionMaterial;

            _rimParts.Add (_polygon);
            _rimLofters.Add (polyLofter);
        }

        _rimCount = 0;
        foreach (PolygonLofter lofter in _rimLofters)
        {
            _rimCount += lofter.GetRimCount ();
        }

        _rimCount += _corners.Count;
    }
Ejemplo n.º 6
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;
    }