THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 26/07/2012 at 10:54, xxxxxxxx wrote:
In case it's useful, here is some code that I cobbled together from some older SDK example code...
//------------------------------------------------------------------------------------------------------
//******************************************************************************************************
// FrontalMapUVs() - perform a simple 'frontal' uv-mapping
//******************************************************************************************************
//------------------------------------------------------------------------------------------------------
#define SIGDIG 5.0
static Real sign(Real n)
{
if( n > 0.0 ) return 1.0;
if( n < 0.0 ) return -1.0;
return 0.0;
}
static Real TrimDecimal(Real num, Real digits)
{
Real n;
n = num * Pow((Real)10.0, digits);
n = sign(n) * Abs(Floor(n + 0.5));
return n / Pow((Real)10.0, digits);
}
Bool FrontalMapUVs(PolygonObject *op, Matrix mg)
{
if( !op ) return false;
LONG numFaces = op->GetPolygonCount();
LONG numVerts = op->GetPointCount();
Vector *pVerts = op->GetPointW();
CPolygon *pPolys = op->GetPolygonW();
UVWTag *pUVTag = (UVWTag * )op->MakeVariableTag(Tuvw, numFaces);
if( !pUVTag )
return false;
#ifdef _R12_SDK_
UVWHandle pUVHndl = pUVTag->GetDataAddressW();
if( !pUVHndl )
return false;
#elif _R11p5_SDK_
void *pUVHndl = pUVTag->GetDataAddressW();
if( !pUVHndl )
return false;
#else
void *pUVHndl = NULL;
#endif
LONG ndx;
Real lenxinv, lenyinv, lenzinv;
Vector mapCenter, mapSize, vMin, vMax;
vMin.x = 100000.0;
vMin.y = 100000.0;
vMin.z = 100000.0;
vMax.x = -100000.0;
vMax.y = -100000.0;
vMax.z = -100000.0;
for(ndx=0; ndx<numVerts; ndx++)
{
Vector pt = pVerts[ndx] * mg;
if( pt.x < vMin.x ) vMin.x = pt.x;
if( pt.x > vMax.x ) vMax.x = pt.x;
if( pt.y < vMin.y ) vMin.y = pt.y;
if( pt.y > vMax.y ) vMax.y = pt.y;
if( pt.z < vMin.z ) vMin.z = pt.z;
if( pt.z > vMax.z ) vMax.z = pt.z;
}
mapSize.x = Abs(vMax.x - vMin.x);
mapSize.y = Abs(vMax.y - vMin.y);
mapSize.z = Abs(vMax.z - vMin.z);
mapCenter.x = vMin.x+(mapSize.x*0.5);
mapCenter.y = vMin.y+(mapSize.y*0.5);
mapCenter.z = vMin.z+(mapSize.z*0.5);
if (mapSize.x!=0.0) lenxinv = 1.0/mapSize.x; else lenxinv = 0.0;
if (mapSize.y!=0.0) lenyinv = 1.0/mapSize.y; else lenyinv = 0.0;
if (mapSize.z!=0.0) lenzinv = 1.0/mapSize.z; else lenzinv = 0.0;
// Walk the list of polygons and map the UVs
for(ndx=0; ndx<numFaces; ndx++)
{
UVWStruct uvw;
cmpUVGet(pUVTag, pUVHndl, ndx, uvw);
Vector pt_a = (pVerts[pPolys[ndx].a] - mapCenter) + mg.off;
Vector pt_b = (pVerts[pPolys[ndx].b] - mapCenter) + mg.off;
Vector pt_c = (pVerts[pPolys[ndx].c] - mapCenter) + mg.off;
Vector pt_d = (pVerts[pPolys[ndx].d] - mapCenter) + mg.off;
uvw.a.x = TrimDecimal((pt_a.x*lenxinv)+0.5, SIGDIG);
uvw.a.y = TrimDecimal((-pt_a.y*lenyinv)+0.5, SIGDIG);
uvw.b.x = TrimDecimal((pt_b.x*lenxinv)+0.5, SIGDIG);
uvw.b.y = TrimDecimal((-pt_b.y*lenyinv)+0.5, SIGDIG);
uvw.c.x = TrimDecimal((pt_c.x*lenxinv)+0.5, SIGDIG);
uvw.c.y = TrimDecimal((-pt_c.y*lenyinv)+0.5, SIGDIG);
uvw.d.x = TrimDecimal((pt_d.x*lenxinv)+0.5, SIGDIG);
uvw.d.y = TrimDecimal((-pt_d.y*lenyinv)+0.5, SIGDIG);
cmpUVSet(pUVTag, pUVHndl, ndx, uvw);
}
return true;
}
...note that I call that routine IF the mesh is not already uv-mapped...
// start by grabbing the current UVWTag
UVWTag *pSrcUVs = (UVWTag* )(op->GetTag(Tuvw, 0));
if( !pSrcUVs )
{
// if not already mapped, do a simple frontal mapping
if( !FrontalMapUVs(op, op->GetMgn()) )
return NULL;
....
...also note that I'm just passing the mesh's global matrix, so you could remove that argument and just grab it inside that routine.
The only other note is the "cmpUVGet()/cmpUVSet()" calls... those are calls to my version-compatibility routines...
//-------------------------------------------------------------
// cmpUVGet()
//-------------------------------------------------------------
void cmpUVGet(UVWTag *pUVWTag, UVWHandle pUVHndl, LONG ndx, UVWStruct& uvw)
{
#ifdef _R11p5_SDK_
if( pUVWTag && pUVHndl ) pUVWTag->Get(pUVHndl, ndx, uvw);
#else
if( pUVWTag ) uvw = pUVWTag->Get(ndx);
#endif
}
//-------------------------------------------------------------
// cmpUVSet()
//-------------------------------------------------------------
void cmpUVSet(UVWTag *pUVWTag, UVWHandle pUVHndl, LONG ndx, const UVWStruct& uvw)
{
#ifdef _R11p5_SDK_
if( pUVWTag && pUVHndl ) pUVWTag->Set(pUVHndl, ndx, uvw);
#else
if( pUVWTag ) pUVWTag->Set(ndx, uvw);
#endif
}
...where my _Rxx_SDK_ defines are cumulative (ie. R11.5 is also defined in my R12 (and later) builds and R11.5 and R12 defines are also defined in my R13 (and later) builds, along with the R13 define, etc.). This is a carry-over from long, long ago... I'm in the process of changing over to a "#if API_VERSION < 13000" type system.