Ejemplo n.º 1
0
String DxBuilder::buildStructs(const ASTEffect& effect, const ASTFunction& function)
{
   typedef std::vector<const ASTStruct*> Structs;
   Structs structs;

   if ( function.mpType->isStruct() )
   {
      const ASTStruct& aststruct = function.mpType->getStruct();
      structs.push_back(&aststruct);
   }   
   
   for ( std::size_t index = 0; index < function.mArguments.size(); ++index )
   {
      const ASTFunctionArgument* parg = function.mArguments[index];
      if ( parg->mpType->isStruct() )
      {
         int s = 0;
         const ASTStruct& aststruct = parg->mpType->getStruct();
         for ( ; s < structs.size(); ++s )
         {
            if ( structs[s] == &aststruct )
            {
               break;
            }
         }

         if ( s == structs.size() )
         {
            structs.push_back(&aststruct);
         }
      }
   }

   String code;
   for ( std::size_t index = 0; index < structs.size(); ++index )
   {
      const ASTStruct* pstruct = structs[index];
      code += buildStruct(*pstruct);
   }
   return code;
}
Ejemplo n.º 2
0
void Heightfield::fillProperties(ParsedBlock& pb)
{
    Bitmap* bmp = NULL;
    if (!pb.getBitmapFileProp("file", &bmp, filename)) pb.requiredProp("file");
    W = bmp->getWidth();
    H = bmp->getHeight();
    blur = 0;
    pb.getDoubleProp("blur", &blur);
    heights = new float[W * H];
    float minY = LARGE_FLOAT, maxY = -LARGE_FLOAT;
    // do we have blur? if no, just fetch the source image and store it:
    if (blur <= 0) {
        for (int y = 0; y < H; y++)
            for (int x = 0; x < W; x++) {
                float h = bmp->getPixel(x, y).intensity();
                heights[y * W + x] = h;
                minY = min(minY, h);
                maxY = max(maxY, h);
            }
    } else {
        // We have blur...
        // 1) convert image to greyscale (if not already):
        for (int y = 0; y < H; y++) {
            for (int x = 0; x < W; x++) {
                float f = bmp->getPixel(x, y).intensity();
                bmp->setPixel(x, y, Color(f, f, f));
            }
        }
        // 2) calculate the gaussian coefficients, see http://en.wikipedia.org/wiki/Gaussian_blur
        static float gauss[128][128];
        int R = min(128, nearestInt(float(3 * blur)));
        for (int y = 0; y < R; y++)
            for (int x = 0; x < R; x++)
                gauss[y][x] = float(exp(-(sqr(x) + sqr(y))/(2 * sqr(blur))) / (2 * PI * sqr(blur)));
        // 3) apply gaussian blur with the specified number of blur units:
        // (this is potentially slow for large blur radii)
        for (int y = 0; y < H; y++) {
            for (int x = 0; x < W; x++) {
                float sum = 0;
                for (int dy = -R + 1; dy < R; dy++)
                    for (int dx = -R + 1; dx < R; dx++)
                        sum += gauss[abs(dy)][abs(dx)] * bmp->getPixel(x + dx, y + dy).r;
                heights[y * W + x] = sum;
                minY = min(minY, sum);
                maxY = max(maxY, sum);
            }
        }
    }
    // set the bounding box. minY and maxY are the bbox extents along Y and are calculated
    // from the heights[] array.
    bbox.vmin = Vector(0, minY, 0);
    bbox.vmax = Vector(W, maxY, H);

    // calculate the maxH array. maxH(x, y) = max(H(x, y), H(x + 1, y), H(x, y + 1), H(x + 1, y+1))
    maxH = new float[W*H];
    for (int y = 0; y < H; y++)
        for (int x = 0; x < W; x++) {
            float& maxH = this->maxH[y * W + x];
            maxH = heights[y * W + x];
            if (x < W - 1) maxH = max(maxH, heights[y * W + x + 1]);
            if (y < H - 1) {
                maxH = max(maxH, heights[(y + 1) * W + x]);
                if (x < W - 1)
                    maxH = max(maxH, heights[(y + 1) * W + x + 1]);
            }
        }
    // precalculate the normals at each integer point. We create normals by doing two forward differences
    // on the height along x and y at each point and using the cross product of these differences to
    // obtain the normal vector
    normals = new Vector[W * H];
    for (int y = 0; y < H; y++)
        for (int x = 0; x < W; x++) {
            float h0 = heights[y * W + x];
            float hdx = heights[y * W + min(W - 1, x + 1)];
            float hdy = heights[min(H - 1, y + 1) * W + x];
            Vector vdx = Vector(1, hdx - h0, 0); // forward difference along X
            Vector vdy = Vector(0, hdy - h0, 1); // forward difference along Z
            Vector norm = vdy ^ vdx;
            norm.normalize();
            normals[y * W + x] = norm;
        }
    useOptimization = false;
    pb.getBoolProp("useOptimization", &useOptimization);
    if (!disableAcceleratedStructures && useOptimization) {
        Uint32 clk = SDL_GetTicks();
        buildStruct();
        clk = SDL_GetTicks() - clk;
        printf("Heightfield acceleration struct built in %.3lfs\n", clk / 1000.0);
    }
}