Beispiel #1
0
void GlobalSettings::fillProperties(ParsedBlock& pb)
{
	pb.getIntProp("frameWidth", &frameWidth);
	pb.getIntProp("frameHeight", &frameHeight);
	pb.getColorProp("ambientLight", &ambientLight);
	pb.getIntProp("maxTraceDepth", &maxTraceDepth);
	pb.getBoolProp("dbg", &dbg);
	pb.getBoolProp("wantPrepass", &wantPrepass);
	pb.getBoolProp("wantAA", &wantAA);
	pb.getDoubleProp("aaThresh", &aaThresh);
}
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);
    }
}