Torque 3D 3.8
ContentsIndexHome
PreviousUpNext
GFXUtil::DistanceField::makeDistanceField Function
Syntax
C++
void makeDistanceField(const U8 * sourceData, S32 sourceSizeX, S32 sourceSizeY, U8 * targetData, S32 targetSizeX, S32 targetSizeY, F32 radius);

GBitmap * makeDistanceField(const GBitmap * sourceBmp, S32 targetSizeX, S32 targetSizeY, F32 rangePct); 

GBitmap * GFXUtil::DistanceField::makeDistanceField(GBitmap * sourceBmp, S32 targetSizeX, S32 targetSizeY, F32 rangePct) { AssertFatal(sourceBmp->getFormat() == GFXFormatA8,"Use an alpha-only texture to create distance fields"); 

static VectorsearchSpace; 

S32 sourceSizeX = sourceBmp->getWidth(); S32 sourceSizeY = sourceBmp->getHeight(); 

S32 targetToSourceScalarX = sourceSizeX / targetSizeX; S32 targetToSourceScalarY = sourceSizeY / targetSizeY; S32 targetToSourcePixOffsetX = targetToSourceScalarX / 2; S32 targetToSourcePixOffsetY = targetToSourceScalarY / 2; 

F32 range = getMin(sourceSizeX,sourceSizeY) * rangePct; F32 range2 = range * 2.f; 

{ S32 intRange = mCeil(range); for(S32 spaceY = -intRange; spaceY < intRange; spaceY++) { for(S32 spaceX = -intRange; spaceX < intRange; spaceX++) { if(spaceX == 0 && spaceY == 0) continue; 

F32 distance = Point2F(spaceX,spaceY).len(); if(distance <= range) { searchSpace.increment(); searchSpace.last().distance = distance; searchSpace.last().xOffset = spaceX; searchSpace.last().yOffset = spaceY; } } } } dQsort(searchSpace.address(), searchSpace.size(), sizeof(DistanceFieldSearchSpaceStruct), cmpSortDistanceFieldSearchSpaceStruct); 

GBitmap * targetBmp = new GBitmap(targetSizeX,targetSizeY,false,GFXFormatA8); 

U8 * targetPixel = targetBmp->getWritableBits(); for(S32 y = 0; y < targetSizeY; y++) { for(S32 x = 0; x < targetSizeX; x++) { S32 sourceX = x * targetToSourceScalarX + targetToSourcePixOffsetX; S32 sourceY = y * targetToSourceScalarY + targetToSourcePixOffsetY; 

const U8 * thisPixel = sourceBmp->getAddress(sourceX,sourceY); 

bool thisPixelEmpty = *thisPixel == 0; 

F32 closestDist = F32_MAX

for(DistanceFieldSearchSpaceStruct * seachSpaceStructPtr = searchSpace.begin(); seachSpaceStructPtr <= searchSpace.end(); seachSpaceStructPtr++) { DistanceFieldSearchSpaceStruct & searchSpaceStruct = *seachSpaceStructPtr; S32 cx = sourceX + searchSpaceStruct.xOffset; if(cx < 0 || cx >= sourceSizeX) continue; 

S32 cy = sourceY + searchSpaceStruct.yOffset; if(cy < 0 || cy >= sourceSizeY) continue; 

const U8 * checkPixel = sourceBmp->getAddress(cx,cy); if((*checkPixel == 0) != thisPixelEmpty) { closestDist = searchSpaceStruct.distance; break; } } 

F32 diff = thisPixelEmpty ? getMax(-0.5f,-(closestDist / range2)) : getMin(0.5f,closestDist / range2); F32 targetValue = 0.5f + diff; 

*targetPixel = targetValue * 255; targetPixel++; } } 

searchSpace.clear(); 

return targetBmp;

Copyright (c) 2015. All rights reserved.
What do you think about this topic? Send feedback!