Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- procedure TALEForm.Grass(polyn:integer; NV, NV2:TRPoint; GHeight:double; Smoothing, CorrectREdge, GWidth:boolean);
- var
- maxx: integer;
- i, j: integer;
- Pol: TPolygon;
- IsCreating: boolean;
- RightOrient, RightSlope: boolean;
- Modif: boolean;
- istart, iend, im1, ip1, l:integer;
- v1, v2, v: TRPoint;
- coss, sins, tmp: double;
- startheight, endheight, wh: double;
- function GetBVector(v1, v2: TRPoint): TRPoint;
- var
- v: TRPoint;
- cosa: double;
- begin
- Level.Normalize(v1);
- Level.Normalize(v2);
- v.x := v1.x+v2.x;
- v.y := v1.y+v2.y;
- Level.Normalize(v);
- if (v.x = 0) and (v.y = 0) then begin
- //Âåêòîðû ïàðàëëåëüíû
- v.x := v1.y;
- v.y := -v1.x;
- end;
- if v.y<0 then begin
- //Íàäî âíèç, à íå ââåðõ
- v.x := -v.x;
- v.y := -v.y;
- end;
- cosa := v1.x*v.x+v1.y*v.y;
- cosa := sqrt(1-cosa*cosa);
- if cosa<>0 then begin
- v.x := v.x/cosa;
- v.y := v.y/cosa;
- end else begin Level.AddMessage(Format(MessageString[63], [0]), iWarning) end;
- //Grass error 0 - âåêòîðû ïàðàëëåëüíû
- //ïî èäåå, íå áûâàåò
- Result := v;
- end;
- begin
- with Level do begin
- if not FullTopChecked then begin CheckTopology(NV, true) end;
- l := Length(Polygons[polyn].Vertices);
- //MasSlope - tg
- //Íàéäåì sin è cos
- sins := MaxSlope/sqrt(sqr(MaxSlope)+1);
- coss := sqrt(1-sqr(sins));
- maxx := 0;
- for i := 1 to l-1 do begin if Polygons[polyn].Vertices[maxx].x<Polygons[polyn].Vertices[i].x then begin maxx := i end end;
- i := maxx;
- IsCreating := true;
- Pol.Grass := 1;
- SetLength(Pol.Vertices, 0);
- Modif := false;
- istart := i;
- repeat
- //Äîáàâëåíèå âåðøèíû
- if IsCreating then begin
- SetLength(Pol.Vertices, Length(Pol.Vertices)+1);
- Pol.Vertices[High(Pol.Vertices)] := Polygons[polyn].Vertices[i];
- with Pol.Vertices[High(Pol.Vertices)] do begin if GWidth then begin
- im1 := (i-1+l) mod l;
- ip1 := (i+1) mod l;
- v1.x := Polygons[polyn].Vertices[i].x-Polygons[polyn].Vertices[im1].x;
- v1.y := Polygons[polyn].Vertices[i].y-Polygons[polyn].Vertices[im1].y;
- v2.x := Polygons[polyn].Vertices[i].x-Polygons[polyn].Vertices[ip1].x;
- v2.y := Polygons[polyn].Vertices[i].y-Polygons[polyn].Vertices[ip1].y;
- v := GetBVector(v1, v2);
- x := x+v.x*GHeight;
- y := y+v.y*GHeight;
- end else begin y := y+GHeight end end;
- end;
- NV := Polygons[polyn].Vertices[(i+1) mod l];
- RightOrient := (Polygons[polyn].Vertices[i].x>NV.x);
- RightSlope := (abs(Polygons[polyn].Vertices[i].x-NV.x)>MaxSlope*abs(Polygons[polyn].Vertices[i].y-NV.y));
- if not (RightOrient and RightSlope) then begin
- //Ñâåðòûâàíèå
- if IsCreating then begin
- iend := i;
- if Length(Pol.Vertices)>=2 then begin
- startheight := GHeight;
- endheight := GHeight;
- //Íà êðàÿõ ðîâíî âíèç
- if GWidth then begin
- //Åñëè íå "ãëàäêî"
- if (Pol.Vertices[1].x<Polygons[polyn].Vertices[istart].x) or (Length(Pol.Vertices) = 2) then begin
- ip1 := (istart+1) mod l;
- v1.x := Polygons[polyn].Vertices[istart].x-Polygons[polyn].Vertices[ip1].x;
- v1.y := Polygons[polyn].Vertices[istart].y-Polygons[polyn].Vertices[ip1].y;
- v2.x := -v1.x;
- v2.y := v1.y;
- v := GetBVector(v1, v2);
- Pol.Vertices[0].x := Polygons[polyn].Vertices[istart].x+v.x*GHeight;
- Pol.Vertices[0].y := Polygons[polyn].Vertices[istart].y+v.y*GHeight;
- startheight := v.y*GHeight;
- end;
- if (Pol.Vertices[High(Pol.Vertices)-1].x>Polygons[polyn].Vertices[iend].x) or (Length(Pol.Vertices) = 2) then begin
- im1 := (iend-1+l) mod l;
- v2.x := Polygons[polyn].Vertices[iend].x-Polygons[polyn].Vertices[im1].x;
- v2.y := Polygons[polyn].Vertices[iend].y-Polygons[polyn].Vertices[im1].y;
- v1.x := -v2.x;
- v1.y := v2.y;
- v := GetBVector(v1, v2);
- Pol.Vertices[High(Pol.Vertices)].x := Polygons[polyn].Vertices[iend].x+v.x*GHeight;
- Pol.Vertices[High(Pol.Vertices)].y := Polygons[polyn].Vertices[iend].y+v.y*GHeight;
- endheight := v.y*GHeight;
- end;
- end;
- if not Smoothing then begin if Length(Pol.Vertices) = 2 then begin
- SetLength(Pol.Vertices, 3);
- Pol.Vertices[2].x := (Pol.Vertices[0].x+Pol.Vertices[1].x)/2;
- Pol.Vertices[2].y := (Pol.Vertices[0].y+Pol.Vertices[1].y)/2;
- end end;
- //Êîððåêòèðîâêà çàõîäà íà ñëåäóþùóþ ãðàíü
- //Left
- if (Polygons[polyn].Vertices[iend].x<Polygons[polyn].Vertices[(iend+1) mod l].x) then begin
- NV.x := -(Polygons[polyn].Vertices[iend].x-Polygons[polyn].Vertices[(iend-1+l) mod l].x);
- NV.y := -(Polygons[polyn].Vertices[iend].y-Polygons[polyn].Vertices[(iend-1+l) mod l].y);
- NV2.x := -(Polygons[polyn].Vertices[iend].x-Polygons[polyn].Vertices[(iend+1) mod l].x);
- NV2.y := -(Polygons[polyn].Vertices[iend].y-Polygons[polyn].Vertices[(iend+1) mod l].y);
- if (NV.x*NV2.y-NV.y*NV2.x)<0 then begin
- //Òðàâà çàõîäèò çà ñëåä. ãðàíü
- if (NV.x<>0) and (NV2.x<>0) then begin
- if Smoothing then begin wh := WheelHeight end else begin wh := WheelHeight-(Pol.Vertices[High(Pol.Vertices)].y-Polygons[polyn].Vertices[iend].y) end;
- tmp := -wh/(NV2.y/NV2.x-NV.y/NV.x);
- if tmp<0 then begin tmp := 0 end;
- end else begin
- //Íå ïîâåçëî - ïîñëåäíÿÿ ñòîðîíà=0
- tmp := 0;
- Level.AddMessage(Format(MessageString[63], [1]), iWarning);
- end;
- if (tmp<NV.x) then begin
- Pol.Vertices[High(Pol.Vertices)].x := Pol.Vertices[High(Pol.Vertices)].x+tmp;
- Pol.Vertices[High(Pol.Vertices)].y := Pol.Vertices[High(Pol.Vertices)].y+tmp*NV.y/NV.x;
- end else begin
- //Óäàëÿåì ïîñëåäíþþ âåðøèíó
- SetLength(Pol.Vertices, High(Pol.Vertices));
- AddMessage(Format(MessageString[63], [2]), iWarning);
- end;
- end;
- end;
- //Right
- if (Polygons[polyn].Vertices[istart].x>Polygons[polyn].Vertices[(istart+1) mod l].x) then begin
- NV2.x := -(Polygons[polyn].Vertices[istart].x-Polygons[polyn].Vertices[(istart-1+l) mod l].x);
- NV2.y := -(Polygons[polyn].Vertices[istart].y-Polygons[polyn].Vertices[(istart-1+l) mod l].y);
- NV.x := -(Polygons[polyn].Vertices[istart].x-Polygons[polyn].Vertices[(istart+1) mod l].x);
- NV.y := -(Polygons[polyn].Vertices[istart].y-Polygons[polyn].Vertices[(istart+1) mod l].y);
- if (NV.x*NV2.y-NV.y*NV2.x)>0 then begin
- //Òðàâà çàõîäèò çà ñëåä. ãðàíü
- if (NV.x<>0) and (NV2.x<>0) then begin
- if Smoothing then begin wh := WheelHeight end else begin wh := WheelHeight-(Pol.Vertices[0].y-Polygons[polyn].Vertices[istart].y) end;
- tmp := wh/(NV2.y/NV2.x-NV.y/NV.x);
- if tmp<0 then begin tmp := 0 end;
- end else begin
- //Íå ïîâåçëî - ïîñëåäíÿÿ ñòîðîíà=0
- tmp := 0;
- AddMessage(Format(MessageString[63], [1]), iWarning);
- end;
- if (tmp<-NV.x) then begin
- Pol.Vertices[0].x := Pol.Vertices[0].x-tmp;
- Pol.Vertices[0].y := Pol.Vertices[0].y-tmp*NV.y/NV.x;
- end else begin
- //Óäàëÿåì ïîñëåäíþþ âåðøèíó
- for j := 0 to High(Pol.Vertices)-1 do begin Pol.Vertices[j] := Pol.Vertices[j+1] end;
- SetLength(Pol.Vertices, High(Pol.Vertices));
- AddMessage(Format(MessageString[63], [2]), iWarning);
- end;
- end;
- end;
- //Êîððåêòèðîâêà ïðàâîãî êðàÿ
- if CorrectREdge then begin
- Pol.Vertices[0].x := Pol.Vertices[0].x-MaxGrassWidth;
- end;
- //Íåáîëüøîå ñóæåíèå êðàåâ
- Pol.Vertices[0].x := Pol.Vertices[0].x-1e-7;
- Pol.Vertices[High(Pol.Vertices)].x := Pol.Vertices[High(Pol.Vertices)].x+1e-7;
- //Ñãëàæèâàíèå
- if Smoothing then begin
- SetLength(Pol.Vertices, Length(Pol.Vertices)+2);
- //Right
- v.x := Pol.Vertices[1].x-Pol.Vertices[0].x;
- v.y := Pol.Vertices[1].y-Pol.Vertices[0].y;
- Normalize(v);
- v1 := v;
- v.x := v1.x*coss+v1.y*sins;
- v.y := v1.y*coss-v1.x*sins;
- v.x := v.x/sins*GHeight;
- v.y := v.y/sins*GHeight;
- if not GWidth then begin
- tmp := v1.x/v1.y/sqrt(sqr(v1.x/v1.y)+1);
- v.x := v.x*tmp;
- v.y := v.y*tmp;
- end;
- if v.x>0 then begin
- v.x := -v.x;
- v.y := -v.y;
- end;
- Pol.Vertices[High(Pol.Vertices)].x := Pol.Vertices[0].x;
- Pol.Vertices[High(Pol.Vertices)].y := Pol.Vertices[0].y-startheight-GHeight*0.01;
- Pol.Vertices[0].x := Pol.Vertices[0].x+v.x;
- Pol.Vertices[0].y := Pol.Vertices[0].y-startheight+v.y;
- //Left
- v.x := Pol.Vertices[High(Pol.Vertices)-3].x-Pol.Vertices[High(Pol.Vertices)-2].x;
- v.y := Pol.Vertices[High(Pol.Vertices)-3].y-Pol.Vertices[High(Pol.Vertices)-2].y;
- Normalize(v);
- v1 := v;
- v.x := v1.x*coss-v1.y*sins;
- v.y := v1.y*coss+v1.x*sins;
- v.x := v.x/sins*GHeight;
- v.y := v.y/sins*GHeight;
- if not GWidth then begin
- tmp := v1.x/v1.y/sqrt(sqr(v1.x/v1.y)+1);
- v.x := v.x*tmp;
- v.y := v.y*tmp;
- end;
- if v.x<0 then begin
- v.x := -v.x;
- v.y := -v.y;
- end;
- Pol.Vertices[High(Pol.Vertices)-1].x := Pol.Vertices[High(Pol.Vertices)-2].x;
- Pol.Vertices[High(Pol.Vertices)-1].y := Pol.Vertices[High(Pol.Vertices)-2].y-endheight-GHeight*0.01;
- Pol.Vertices[High(Pol.Vertices)-2].x := Pol.Vertices[High(Pol.Vertices)-2].x+v.x;
- Pol.Vertices[High(Pol.Vertices)-2].y := Pol.Vertices[High(Pol.Vertices)-2].y-endheight+v.y;
- { Pol.Vertices[High(Pol.Vertices)-1]:=Pol.Vertices[High(Pol.Vertices)-2];
- Pol.Vertices[High(Pol.Vertices)-1].y:=Pol.Vertices[High(Pol.Vertices)-1].y-GHeight*1.2;
- Pol.Vertices[High(Pol.Vertices)-2].x:=Pol.Vertices[High(Pol.Vertices)-2].x+0.2;}
- end;
- //---
- if not Modif then begin
- Modif := true;
- Modified := true;
- end;
- AddPolygon(Pol);
- end;
- SetLength(Pol.Vertices, 0);
- IsCreating := false;
- end;
- end else begin
- if not IsCreating then begin
- dec(i);
- IsCreating := true;
- istart := i+1;
- end;
- end;
- inc(i);
- i := i mod l;
- until (i = maxx);
- end;
- end;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement