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; } }
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; }