NL3D::CPatchUVLocator Class Reference

#include <patchuv_locator.h>


Detailed Description

From a patch and UV coordinate in [0,OrderS], [0,OrderT], retrieve the appropriate coordinate in neighborhood.
Author:
Lionel Berenguier

Nevrax France

Date:
2001

Definition at line 45 of file patchuv_locator.h.

Public Member Functions

void build (const CPatch *patchCenter, sint edgeCenter, CPatch::CBindInfo &bindInfo)
void locateUV (const NLMISC::CVector2f &uvIn, uint patch, CPatch *&patchOut, NLMISC::CVector2f &uvOut)
bool sameEdgeOrder () const
uint selectPatch (const NLMISC::CVector2f &uvIn)

Private Attributes

CPatch_CenterPatch
sint _CenterPatchEdge
CUVBasis _NeighborBasis [4]
CPatch_NeighborPatch [4]
sint _NPatchs
bool _SameEdgeOrder


Member Function Documentation

void NL3D::CPatchUVLocator::build const CPatch patchCenter,
sint  edgeCenter,
CPatch::CBindInfo bindInfo
 

Definition at line 38 of file patchuv_locator.cpp.

References _CenterPatch, _CenterPatchEdge, _NeighborBasis, _NeighborPatch, _NPatchs, _SameEdgeOrder, NL3D::CPatch::CBindInfo::Edge, NL3D::CPatch::getOrderForEdge(), NL3D::CPatch::getOrderS(), NL3D::CPatch::getOrderT(), NL3D::CPatch::CBindInfo::MultipleBindId, NL3D::CPatch::CBindInfo::MultipleBindNum, NL3D::CPatch::CBindInfo::Next, nlassert, NL3D::CPatch::CBindInfo::NPatchs, NLMISC::CVector2f::set(), sint, NL3D::CPatchUVLocator::CUVBasis::UvI, NLMISC::CVector2f::x, NLMISC::CVector2f::y, and NL3D::CPatch::CBindInfo::Zone.

Referenced by NL3D::CPatch::bind(), NL3D::CZoneCornerSmoother::buildPatchBindInfo(), NL3D::CPatch::computeContinousVertex(), NL3D::CPatch::computeDisplaceCornerSmooth(), NL3D::CPatch::computeDisplaceEdgeSmooth(), NL3D::CPatch::computeDisplaceRawOnNeighbor(), NL3D::CPatch::computeNearBlockLightmap(), NL3D::CPatch::computeNormalCornerSmooth(), NL3D::CPatch::computeNormalEdgeSmooth(), NL3D::CPatch::computeNormalOnNeighbor(), and NL3D::CPatch::computeTileLightmapPixelAroundCorner().

00039 {
00040         nlassert(bindInfo.Zone);
00041         // copy basic. NB: NPatchs==0 means patchCenter is binded on a 1/X patch.
00042         _CenterPatch= const_cast<CPatch*>(patchCenter);
00043         _CenterPatchEdge= edgeCenter;
00044         _NPatchs= bindInfo.NPatchs;
00045 
00046 
00047         // set it to true. false-d if one of the neighbor patch does not have same number of tile.
00048         _SameEdgeOrder= true;
00049 
00050 
00051         // For all patchs binded to me.
00052         for(sint i=0; i<_NPatchs; i++)
00053         {
00054                 // The edge of the neihbor on which we are binded.
00055                 sint    edgeNeighbor= bindInfo.Edge[i];
00056                 CPatch  *paNeighbor= bindInfo.Next[i];
00057                 _NeighborPatch[i]= paNeighbor;
00058 
00059 
00060                 // Find uvI, uvJ, uvP such that: 
00061                 // uvOut= uvIn.x * uvI + uvIn.y * uvJ + uvP.
00062                 CVector2f               &uvI= _NeighborBasis[i].UvI;
00063                 CVector2f               &uvJ= _NeighborBasis[i].UvJ;
00064                 CVector2f               &uvP= _NeighborBasis[i].UvP;
00065 
00066 
00067                 // Find the basis MeToNeighbor.
00068                 //=============================
00069                 sint    rotation= (edgeCenter - edgeNeighbor + 4) & 3;
00070                 // Find scale to apply.
00071                 float   scX, scY;
00072                 // If our neighbor edge is a vertical edge
00073                 if( (edgeNeighbor&1)==0 )
00074                 {
00075                         scX= 1;
00076 
00077                         // Manage difference of Order at the edge.
00078                         scY= (float)paNeighbor->getOrderForEdge(edgeNeighbor) / (float)patchCenter->getOrderForEdge(edgeCenter);
00079                         // Manage bind on the edge.
00080                         // If patchCenter is binded on a bigger
00081                         if(bindInfo.MultipleBindNum!=0)
00082                                 scY/= bindInfo.MultipleBindNum;
00083                         if(_NPatchs>1)
00084                                 scY*= _NPatchs;
00085                         // same TileOrder on the edge??
00086                         if(scY!=1)
00087                                 _SameEdgeOrder= false;
00088                 }
00089                 else
00090                 {
00091                         scY= 1;
00092 
00093                         // Manage difference of Order at the edge.
00094                         scX= (float)paNeighbor->getOrderForEdge(edgeNeighbor) / (float)patchCenter->getOrderForEdge(edgeCenter);
00095                         // Manage bind on the edge.
00096                         // If patchCenter is binded on a bigger
00097                         if(bindInfo.MultipleBindNum!=0)
00098                                 scX/= bindInfo.MultipleBindNum;
00099                         if(_NPatchs>1)
00100                                 scX*= _NPatchs;
00101                         // same TileOrder on the edge??
00102                         if(scX!=1)
00103                                 _SameEdgeOrder= false;
00104                 }
00105                 // Find rotation to apply.
00106                 switch(rotation)
00107                 {
00108                 case 0: uvI.set(-scX, 0); uvJ.set(0, -scY);     break;
00109                 case 1: uvI.set(0, -scY); uvJ.set(scX, 0);      break;
00110                 case 2: uvI.set(scX, 0); uvJ.set(0, scY);       break;
00111                 case 3: uvI.set(0, scY); uvJ.set(-scX, 0);      break;
00112                 }
00113 
00114 
00115                 // Find the position.
00116                 //=============================
00117                 // Find the uv coord at start of the edge, for 2 patchs.
00118                 CVector2f               uvCenter;
00119                 CVector2f               uvNeighbor;
00120                 float   decal;
00121 
00122                 // find the uv at start of edgeCenter, + decal due to bind 1/X.
00123                 float   ocS= patchCenter->getOrderS();
00124                 float   ocT= patchCenter->getOrderT();
00125                 // Manage Bind 1/X.
00126                 if(_NPatchs>1)
00127                 {
00128                         // Move uvCenter, so it is near the position at start of edgeNeighbor.
00129                         decal= (float)i / _NPatchs;
00130                 }
00131                 else
00132                         decal= 0;
00133                 // Manage rotation.
00134                 switch(edgeCenter)
00135                 {
00136                 case 0: uvCenter.set(0, decal*ocT);             break;
00137                 case 1: uvCenter.set(decal*ocS, ocT);   break;
00138                 case 2: uvCenter.set(ocS, (1-decal)*ocT);       break;
00139                 case 3: uvCenter.set((1-decal)*ocS, 0); break;
00140                 };
00141 
00142                 // find the uv at start of edgeNeighbor, + decal due to bind X/1.
00143                 float   onS= paNeighbor->getOrderS();
00144                 float   onT= paNeighbor->getOrderT();
00145                 // Manage Bind X/1.
00146                 if(bindInfo.MultipleBindNum!=0)
00147                 {
00148                         // Must invert the id, because of mirror.... (make a draw).
00149                         sint    id= (bindInfo.MultipleBindNum-1) - bindInfo.MultipleBindId;
00150                         // Move uvNeighbor, so it is near the position at start of edgeCenter.
00151                         decal= (float)id / bindInfo.MultipleBindNum;
00152                 }
00153                 else
00154                         decal= 0;
00155                 // Manage rotation.
00156                 switch(edgeNeighbor)
00157                 {
00158                 case 0: uvNeighbor.set(0, (1-decal)*onT);               break;
00159                 case 1: uvNeighbor.set((1-decal)*onS, onT);     break;
00160                 case 2: uvNeighbor.set(onS, decal*onT);         break;
00161                 case 3: uvNeighbor.set(decal*onS, 0);           break;
00162                 };
00163 
00164 
00165 
00166                 // uvOut= uvIn.x * uvI + uvIn.y * uvJ + uvP.
00167                 // So uvP  = uvOut - uvIn.x * uvI - uvIn.y * uvJ
00168                 uvP= uvNeighbor - uvCenter.x * uvI - uvCenter.y * uvJ;
00169 
00170         }
00171 }

void NL3D::CPatchUVLocator::locateUV const NLMISC::CVector2f uvIn,
uint  patch,
CPatch *&  patchOut,
NLMISC::CVector2f uvOut
 

Definition at line 202 of file patchuv_locator.cpp.

References _NeighborBasis, _NeighborPatch, _NPatchs, NL3D::CPatchUVLocator::CUVBasis::mulPoint(), and uint.

Referenced by NL3D::CPatch::bind(), NL3D::CPatch::computeContinousVertex(), NL3D::CPatch::computeDisplaceCornerSmooth(), NL3D::CPatch::computeDisplaceEdgeSmooth(), NL3D::CPatch::computeDisplaceRawOnNeighbor(), NL3D::CPatch::computeNearBlockLightmap(), NL3D::CPatch::computeNormalCornerSmooth(), NL3D::CPatch::computeNormalEdgeSmooth(), NL3D::CPatch::computeNormalOnNeighbor(), and NL3D::CPatch::computeTileLightmapPixelAroundCorner().

00203 {
00204         if(_NPatchs==1)
00205         {
00206                 // Change basis and select good patch.
00207                 _NeighborBasis[0].mulPoint(uvIn, uvOut);
00208                 patchOut= _NeighborPatch[0];
00209         }
00210         else
00211         {
00212                 // Change basis and select good patch.
00213                 _NeighborBasis[patch].mulPoint(uvIn, uvOut);
00214                 patchOut= _NeighborPatch[patch];
00215         }
00216 }

bool NL3D::CPatchUVLocator::sameEdgeOrder  )  const [inline]
 

return true only if the 2 edges have same number of tiles. bind 1/X case: return true only if ALL the adjacents patchs respect this rule. So you are sure that for all the src patch, one tile has exaclty one neighbor tile near him.

Definition at line 66 of file patchuv_locator.h.

References _SameEdgeOrder.

Referenced by NL3D::CZoneCornerSmoother::buildPatchBindInfo(), and NL3D::CPatch::computeNearBlockLightmap().

00066 {return _SameEdgeOrder;}

uint NL3D::CPatchUVLocator::selectPatch const NLMISC::CVector2f uvIn  ) 
 

Definition at line 175 of file patchuv_locator.cpp.

References _CenterPatch, _CenterPatchEdge, _NPatchs, NLMISC::clamp(), NL3D::CPatch::getOrderS(), NL3D::CPatch::getOrderT(), sint, uint, NLMISC::CVector2f::x, and NLMISC::CVector2f::y.

Referenced by NL3D::CPatch::bind(), NL3D::CPatch::computeContinousVertex(), NL3D::CPatch::computeDisplaceCornerSmooth(), NL3D::CPatch::computeDisplaceEdgeSmooth(), NL3D::CPatch::computeDisplaceRawOnNeighbor(), NL3D::CPatch::computeNearBlockLightmap(), NL3D::CPatch::computeNormalCornerSmooth(), NL3D::CPatch::computeNormalEdgeSmooth(), NL3D::CPatch::computeNormalOnNeighbor(), and NL3D::CPatch::computeTileLightmapPixelAroundCorner().

00176 {
00177         if(_NPatchs==1)
00178                 return 0;
00179         else
00180         {
00181                 // Choice before on which patch we must go.
00182                 float   selection=0.0;
00183                 uint    os= _CenterPatch->getOrderS();
00184                 uint    ot= _CenterPatch->getOrderT();
00185                 switch(_CenterPatchEdge)
00186                 {
00187                 case 0: selection= uvIn.y / ot; break;
00188                 case 1: selection= uvIn.x / os; break;
00189                 case 2: selection= (ot-uvIn.y) / ot; break;
00190                 case 3: selection= (os-uvIn.x) / os; break;
00191                 }
00192 
00193                 sint    sel= (sint)floor(selection*_NPatchs);
00194                 clamp(sel, 0, _NPatchs-1);
00195 
00196                 return sel;
00197         }
00198 }


Field Documentation

CPatch* NL3D::CPatchUVLocator::_CenterPatch [private]
 

Definition at line 82 of file patchuv_locator.h.

Referenced by build(), and selectPatch().

sint NL3D::CPatchUVLocator::_CenterPatchEdge [private]
 

Definition at line 83 of file patchuv_locator.h.

Referenced by build(), and selectPatch().

CUVBasis NL3D::CPatchUVLocator::_NeighborBasis[4] [private]
 

Definition at line 86 of file patchuv_locator.h.

Referenced by build(), and locateUV().

CPatch* NL3D::CPatchUVLocator::_NeighborPatch[4] [private]
 

Definition at line 85 of file patchuv_locator.h.

Referenced by build(), and locateUV().

sint NL3D::CPatchUVLocator::_NPatchs [private]
 

Definition at line 84 of file patchuv_locator.h.

Referenced by build(), locateUV(), and selectPatch().

bool NL3D::CPatchUVLocator::_SameEdgeOrder [private]
 

Definition at line 87 of file patchuv_locator.h.

Referenced by build(), and sameEdgeOrder().


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 07:01:14 2004 for NeL by doxygen 1.3.6