Linux multi-monitor fullscreen support
[ryzomcore.git] / nel / src / 3d / zone_corner_smoother.cpp
blob568d4c6a3200b3c4954863d99dd772fd4f2665bf
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include "std3d.h"
19 #include "nel/3d/zone_corner_smoother.h"
20 #include "nel/3d/patchuv_locator.h"
22 #ifdef DEBUG_NEW
23 #define new DEBUG_NEW
24 #endif
26 namespace NL3D {
29 // ***************************************************************************
30 CZoneCornerSmoother::CZoneCornerSmoother()
35 // ***************************************************************************
36 void CZoneCornerSmoother::buildPatchBindInfo(CPatch &pa, const CZone::CPatchConnect &pc, bool smoothEdge[4], bool cornerOnBind[4])
38 uint edge, corner;
41 Some terminology here: an edge is supposed going from Corner=edge, to corner=(edge+1)&3.
42 eg: edge 0 goes from corner0 to corner1.
45 for(corner=0; corner<4; corner++)
46 cornerOnBind[corner]= false;
48 // for 4 edges.
49 for(edge=0; edge<4; edge++)
51 // Is this edge smoothed??
52 smoothEdge[edge]= pa.getSmoothFlag(edge);
54 // build bindInfo.
55 CPatch::CBindInfo bindInfo;
56 CPatchUVLocator patchUvLocator;
57 pa.getBindNeighbor(edge, bindInfo);
58 // if neighbor(s) is present.
59 if(bindInfo.Zone)
61 patchUvLocator.build(&pa, edge, bindInfo);
62 // if not sameEdgeOnOrder (NB: all special cases of bind 1/X X/1 managed :) ), not smoothed!
63 if( !patchUvLocator.sameEdgeOrder() )
64 smoothEdge[edge]= false;
66 // Manage bind 1/4 for the 2 patchs on the center of the bind.
67 if(bindInfo.MultipleBindNum==4 && (bindInfo.MultipleBindId==1 || bindInfo.MultipleBindId==2) )
69 // easy, this edge starts and ends on a bind...
70 cornerOnBind[edge]= true;
71 cornerOnBind[(edge+1)&3]= true;
73 // else for case bind 1/2, and for case of patch 0 and patch 3 of the bind 1/4.
74 else if(bindInfo.MultipleBindNum>=2)
76 // Beware of the mirroring!! (make a draw...)
78 ----------|-----------
80 | |
81 1 | |
82 ^ | v
83 | |
84 | *-----------
85 | |
86 | | |
87 0 | |
88 | v
90 ----------|-----------
92 // If we are the patch0 on the neighbor, then we start on a bind, else we ends.
93 if(bindInfo.MultipleBindId==0)
94 cornerOnBind[edge]= true;
95 else
96 cornerOnBind[(edge+1)&3]= true;
104 // ***************************************************************************
105 void CZoneCornerSmoother::updateVertex(uint idVert, uint corner, bool smoothEdge[4], bool cornerOnBind[4])
107 // get or insert into map (with default).
108 CVertexSmoothInfo &vert= VertexMap[idVert];
110 // inc the number of patch binded to this point.
111 vert.NPatchShared++;
113 // get the smooth flag of edge before and after this corner.
114 uint e0= (4+corner-1)&3;
115 uint e1= corner;
116 // if any one of those edge is not smoothed, then this vertex is not smoothed.
117 if( !smoothEdge[e0] || !smoothEdge[e1] )
118 vert.Smoothed= false;
121 // Are we a vertex on a bind??
122 if(cornerOnBind[corner])
123 vert.VertexOnBind= true;
127 // ***************************************************************************
128 void CZoneCornerSmoother::computeAllCornerSmoothFlags(CZone *zone, std::vector<CZone*> neighborZones)
130 nlassert(zone);
131 sint npatchs= zone->getNumPatchs();
132 sint i;
134 VertexMap.clear();
135 IdVertexMap.clear();
137 // for all patchs of the center zone, build the vertexMap.
138 //==================
139 for(i=0; i<npatchs; i++)
141 CPatch &pa= (CPatch&)*(((const CZone*)zone)->getPatch(i));
142 const CZone::CPatchConnect &pc= *(zone->getPatchConnect(i));
143 uint corner;
145 // build bind info for 4 edges and 4 vertices.
146 bool smoothEdge[4];
147 bool cornerOnBind[4];
148 buildPatchBindInfo(pa, pc, smoothEdge, cornerOnBind);
150 // for 4 corners.
151 for(corner=0; corner<4; corner++)
153 // get the vertex id for this patch.
154 uint idVert= pc.BaseVertices[corner];
156 // update this vertex smooth info.
157 updateVertex(idVert, corner, smoothEdge, cornerOnBind);
159 // for Bind with neighbor zones, must insert it in the map CTessVertex* -> VertexId.
160 IdVertexMap[pa.getCornerVertex(corner)]= idVert;
165 // for all patchs of all neigbhors zone, update for vertices that are connected to the centerZone.
166 //==================
167 for(uint nbZone=0; nbZone<neighborZones.size(); nbZone++)
169 CZone *neighborZone= neighborZones[nbZone];
170 nlassert(neighborZone);
171 for(i=0; i<neighborZone->getNumPatchs(); i++)
173 CPatch &pa= (CPatch&)*(((const CZone*)neighborZone)->getPatch(i));
174 const CZone::CPatchConnect &pc= *(neighborZone->getPatchConnect(i));
175 uint corner;
177 // build bind info for 4 edges and 4 vertices.
178 bool smoothEdge[4];
179 bool cornerOnBind[4];
180 buildPatchBindInfo(pa, pc, smoothEdge, cornerOnBind);
182 // for 4 corners.
183 for(corner=0; corner<4; corner++)
185 // try to find the vertex of the centerZone binded to this corner.
186 ItIdVertexMap it= IdVertexMap.find(pa.getCornerVertex(corner));
188 // If this patch is binded on a vertex of the centerZone, must update this vertex.
189 if(it != IdVertexMap.end())
191 // get the vertex id for this patch.
192 uint idVert= it->second;
194 // update this vertex smooth info.
195 updateVertex(idVert, corner, smoothEdge, cornerOnBind);
203 // for all patchs of the center zone, build the finalSmooth.
204 //==================
205 for(i=0; i<npatchs; i++)
207 CPatch &pa= (CPatch&)*(((const CZone*)zone)->getPatch(i));
208 const CZone::CPatchConnect &pc= *(zone->getPatchConnect(i));
209 uint corner;
211 // for 4 corners.
212 for(corner=0; corner<4; corner++)
214 uint idVert= pc.BaseVertices[corner];
215 // get from map.
216 CVertexSmoothInfo &vert= VertexMap[idVert];
218 // the vertex is smoothed if all edges around him are smoothed, AND
219 // if it has 4 patchs around him or if it is a bind.
220 bool finalSmooth;
221 finalSmooth= vert.Smoothed && (vert.VertexOnBind || vert.NPatchShared==4);
223 // update the patch.
224 pa.setCornerSmoothFlag(corner, finalSmooth);
234 } // NL3D