private void RecalcHeight() { _z = _clipmap.GeneratePixelAt(-(_clipmap.Position.X.Integer * 2 - 1), -(_clipmap.Position.Y.Integer * 2 - 1)); var zx = _clipmap.GeneratePixelAt(-(_clipmap.Position.X.Integer * 2 + 1), -(_clipmap.Position.Y.Integer * 2 - 1)); var zy = _clipmap.GeneratePixelAt(-(_clipmap.Position.X.Integer * 2 - 1), -(_clipmap.Position.Y.Integer * 2 + 1)); var zxy = _clipmap.GeneratePixelAt(-(_clipmap.Position.X.Integer * 2 + 1), -(_clipmap.Position.Y.Integer * 2 + 1)); var v1 = Lerp(_z, zx, _clipmap.Position.X.Fraction); var v2 = Lerp(zy, zxy, _clipmap.Position.X.Fraction); _z = Lerp(v1, v2, _clipmap.Position.Y.Fraction); }
/// <summary> /// Generates the height value at the given physical pixel xp/yp /// The pixel coordinates must be within range [0.._d] /// </summary> /// <param name="xp">physical x position</param> /// <param name="yp">physical y position</param> /// <returns></returns> private float GeneratePixelAt2(int xp, int yp) { var d2 = _d / 2; var x = Position.X.Integer; var y = Position.Y.Integer; var cx = (x * 2 + xp) & ~_n; var cy = (y * 2 + yp) & ~_n; var xr = xp - cx - d2; var yr = yp - cy - d2; var xw = xr << _level; var yw = yr << _level; //Debug.Assert((((xw + _scaleInt) / _scaleInt + d2) & _n) == (xp + 1) % _d); //Debug.Assert((((yw + _scaleInt) / _scaleInt + d2) & _n) == (yp + 1) % _d); const float quantizeSteps = 512.0f; var coarsePixel = 0.0f; // any of these values actually must be cached in the parent layer // as the current later lies within it. // the outermost layer will not need to generate the coarse information at all // the maximum visible layer(s) should update in the interior region // as this data needs to be re(used) anyway. var l2 = _level + 1; if (_parent != null) { switch ((xr & 1) | ((yr & 1) << 1)) { case 3: // odd odd (plain parent pixel) { var px1 = (((xw + _scaleInt) >> l2) + d2) & _n; var py1 = (((yw + _scaleInt) >> l2) + d2) & _n; coarsePixel = _parent._cache[py1, px1]; //coarsePixel = _clipmap.GeneratePixelAt(xw + ScaleInt, yw + ScaleInt); break; } case 2: // even/odd { var px0 = (((xw) >> l2) + d2) & _n; var py1 = (((yw + _scaleInt) >> l2) + d2) & _n; var px2 = (((xw + _scaleInt * 2) >> l2) + d2) & _n; coarsePixel = (_parent._cache[py1, px2] + _parent._cache[py1, px0]) * 0.5f; //coarsePixel = (_clipmap.GeneratePixelAt(xw + scaleInt2, yw + ScaleInt) + _clipmap.GeneratePixelAt(xw, yw + ScaleInt)) * 0.5f; break; } case 1: // odd/even { var px1 = (((xw + _scaleInt) >> l2) + d2) & _n; var py0 = (((yw) >> l2) + d2) & _n; var py2 = (((yw + _scaleInt * 2) >> l2) + d2) & _n; coarsePixel = (_parent._cache[py2, px1] + _parent._cache[py0, px1]) * 0.5f; //coarsePixel = (_clipmap.GeneratePixelAt(xw + ScaleInt, yw + scaleInt2) + _clipmap.GeneratePixelAt(xw + ScaleInt, yw)) * 0.5f; break; } case 0: // even/even { var px0 = (((xw) >> l2) + d2) & _n; var px2 = (((xw + _scaleInt * 2) >> l2) + d2) & _n; var py0 = (((yw) >> l2) + d2) & _n; var py2 = (((yw + _scaleInt * 2) >> l2) + d2) & _n; coarsePixel = (_parent._cache[py0, px2] + _parent._cache[py2, px0]) * 0.5f; //coarsePixel = (_clipmap.GeneratePixelAt(xw + scaleInt2, yw) + _clipmap.GeneratePixelAt(xw, yw + scaleInt2)) * 0.5f; break; } } } var finePixel = _clipmap.GeneratePixelAt(xw, yw); _cache[yp, xp] = finePixel; //var finePixel = coarsePixel; var zfzd = ((float)Math.Floor(coarsePixel * quantizeSteps) + finePixel) / quantizeSteps; return(zfzd); }