double sPrimitiveSphere::PrimitiveDistance(CVector3 _point) const { CVector3 point = _point - position; point = rotationMatrix.RotateVector(point); point = point.mod(repeat); double dist = point.Length() - radius; return empty ? fabs(dist) : dist; }
double cPrimitives::PrimitiveSphere(CVector3 _point, const sPrimitiveSphere &sphere) const { CVector3 point = _point - sphere.position; point = sphere.rotationMatrix.RotateVector(point); point = point.mod(sphere.repeat); double dist = point.Length() - sphere.radius; return sphere.empty ? fabs(dist) : dist; }
double sPrimitiveTorus::PrimitiveDistance(CVector3 _point) const { CVector3 point = _point - position; point = rotationMatrix.RotateVector(point); point = point.mod(repeat); double d1 = sqrt(point.x * point.x + point.y * point.y) - radius; double dist = sqrt(d1 * d1 + point.z * point.z) - tube_radius; return empty ? fabs(dist) : dist; }
double sPrimitiveTorus::PrimitiveDistance(CVector3 _point) const { CVector3 point = _point - position; point = rotationMatrix.RotateVector(point); point = point.mod(repeat); double d1 = CVector2<double>(point.x, point.y).LengthPow(pow(2, radiusLPow)) - radius; double dist = CVector2<double>(d1, point.z).LengthPow(pow(2, tubeRadiusLPow)) - tubeRadius; return empty ? fabs(dist) : dist; }
double cPrimitives::PrimitiveTorus(CVector3 _point, const sPrimitiveTorus &torus) const { CVector3 point = _point - torus.position; point = torus.rotationMatrix.RotateVector(point); point = point.mod(torus.repeat); double d1 = sqrt(point.x * point.x + point.y * point.y) - torus.radius; double dist = sqrt(d1 * d1 + point.z * point.z) - torus.tube_radius; return torus.empty ? fabs(dist) : dist; }
double sPrimitiveCylinder::PrimitiveDistance(CVector3 _point) const { CVector3 point = _point - position; point = rotationMatrix.RotateVector(point); point = point.mod(repeat); CVector2<double> cylTemp(point.x, point.y); double dist = cylTemp.Length() - radius; if (!caps) dist = fabs(dist); dist = max(fabs(point.z) - height * 0.5, dist); return empty ? fabs(dist) : dist; }
double cPrimitives::PrimitiveCylinder(CVector3 _point, const sPrimitiveCylinder &cylinder) const { CVector3 point = _point - cylinder.position; point = cylinder.rotationMatrix.RotateVector(point); point = point.mod(cylinder.repeat); CVector2<double> cylTemp(point.x, point.y); double dist = cylTemp.Length() - cylinder.radius; if(!cylinder.caps) dist = fabs(dist); dist = max(fabs(point.z) - cylinder.height * 0.5, dist); return cylinder.empty ? fabs(dist) : dist; }
double sPrimitiveCone::PrimitiveDistance(CVector3 _point) const { CVector3 point = _point - position; point = rotationMatrix.RotateVector(point); point = point.mod(repeat); point.z -= height; float q = sqrt(point.x * point.x + point.y * point.y); CVector2<double> vect(q, point.z); double dist = wallNormal.Dot(vect); if (!caps) dist = fabs(dist); dist = max(-point.z - height, dist); return empty ? fabs(dist) : dist; }
double cPrimitives::PrimitiveCone(CVector3 _point, const sPrimitiveCone &cone) const { CVector3 point = _point - cone.position; point = cone.rotationMatrix.RotateVector(point); point = point.mod(cone.repeat); point.z -= cone.height; float q = sqrt(point.x * point.x + point.y * point.y); CVector2<double> vect(q, point.z); double dist = cone.wallNormal.Dot(vect); if(!cone.caps) dist = fabs(dist); dist = max(-point.z - cone.height, dist); return cone.empty ? fabs(dist) : dist; }
double sPrimitiveBox::PrimitiveDistance(CVector3 _point) const { CVector3 point = _point - position; point = rotationMatrix.RotateVector(point); point = point.mod(repeat); if (empty) { double boxDist = -1e10; boxDist = max(fabs(point.x) - size.x * 0.5, boxDist); boxDist = max(fabs(point.y) - size.y * 0.5, boxDist); boxDist = max(fabs(point.z) - size.z * 0.5, boxDist); return fabs(boxDist); } else { CVector3 boxTemp; boxTemp.x = max(fabs(point.x) - size.x * 0.5, 0.0); boxTemp.y = max(fabs(point.y) - size.y * 0.5, 0.0); boxTemp.z = max(fabs(point.z) - size.z * 0.5, 0.0); return boxTemp.Length() - rounding; } }
double cPrimitives::PrimitiveBox(CVector3 _point, const sPrimitiveBox &box) const { CVector3 point = _point - box.position; point = box.rotationMatrix.RotateVector(point); point = point.mod(box.repeat); if(box.empty) { double boxDist = -1e10; boxDist = max(fabs(point.x) - box.size.x * 0.5, boxDist); boxDist = max(fabs(point.y) - box.size.y * 0.5, boxDist); boxDist = max(fabs(point.z) - box.size.z * 0.5, boxDist); return fabs(boxDist); } else { CVector3 boxTemp; boxTemp.x = max(fabs(point.x) - box.size.x * 0.5, 0.0); boxTemp.y = max(fabs(point.y) - box.size.y * 0.5, 0.0); boxTemp.z = max(fabs(point.z) - box.size.z * 0.5, 0.0); return boxTemp.Length() - box.rounding; } }
sRGBAfloat cRenderWorker::SurfaceColour(const sShaderInputData &input) { #ifdef FAST_MAND double zx = point.x; double zy = point.y; int N = params->N * 10.0; double p = 2.0; double smooth = 0.0; int L = 0; double r = 0.0; int nrKol = 253 * 256; for (L = 0; L < N; L++) { double temp = zx * zx - zy * zy + point.x; zy = 2.0 * zx * zy + point.y; zx = temp; r = zx * zx + zy * zy; if (r > 1e20) { smooth = (L - log(log(sqrt(r)) / log(N)) / log(p)); nrKol = smooth * 50.0; nrKol = abs(nrKol) % (248 * 256); break; } } N_counter += L + 1; Loop_counter++; if (L / 10 < 64) histogram[L / 10]++; else histogram[63]++; return nrKol; #else sRGBAfloat out; switch (data->objectData[input.objectId].objectType) { case fractal::objFractal: { sRGB colour(256, 256, 256); if (input.material->useColorsFromPalette) { int formulaIndex = input.objectId; CVector3 tempPoint = input.point; if (!params->booleanOperatorsEnabled) formulaIndex = -1; else { tempPoint = tempPoint.mod(params->formulaRepeat[formulaIndex]) - params->formulaPosition[formulaIndex]; tempPoint = params->mRotFormulaRotation[formulaIndex].RotateVector(tempPoint); tempPoint *= params->formulaScale[formulaIndex]; } sFractalIn fractIn(tempPoint, 0, params->N * 10, params->common, formulaIndex, input.material->fractalColoring); sFractalOut fractOut; Compute<fractal::calcModeColouring>(*fractal, fractIn, &fractOut); int nrCol = floor(fractOut.colorIndex); nrCol = abs(nrCol) % (248 * 256); int color_number; if (nrCol >= 248 * 256) { color_number = nrCol; } else { color_number = (int)(nrCol * input.material->coloring_speed + 256 * input.material->paletteOffset) % 65536; } colour = input.material->palette.IndexToColour(color_number); } else { colour.R = input.material->color.R / 256.0; colour.G = input.material->color.G / 256.0; colour.B = input.material->color.B / 256.0; } out.R = colour.R / 256.0; out.G = colour.G / 256.0; out.B = colour.B / 256.0; break; } case fractal::objPlane: case fractal::objWater: case fractal::objSphere: case fractal::objBox: case fractal::objRectangle: case fractal::objCircle: case fractal::objCone: case fractal::objTorus: case fractal::objCylinder: { out.R = input.material->color.R / 65536.0; out.G = input.material->color.G / 65536.0; out.B = input.material->color.B / 65536.0; break; } case fractal::objNone: { out = sRGBAfloat(); break; } }; return out; #endif }
double CalculateDistance(const sParamRender ¶ms, const cNineFractals &fractals, const sDistanceIn &in, sDistanceOut *out, sRenderData *data) { double distance; out->objectId = 0; out->totalIters = 0; double limitBoxDist = 0.0; if (params.limitsEnabled) { const double distance_a = max(in.point.x - params.limitMax.x, -(in.point.x - params.limitMin.x)); const double distance_b = max(in.point.y - params.limitMax.y, -(in.point.y - params.limitMin.y)); const double distance_c = max(in.point.z - params.limitMax.z, -(in.point.z - params.limitMin.z)); limitBoxDist = max(max(distance_a, distance_b), distance_c); if (limitBoxDist > in.detailSize) { out->maxiter = false; out->distance = limitBoxDist; out->objectId = 0; out->iters = 0; return limitBoxDist; } } if (params.booleanOperatorsEnabled) { sDistanceIn inTemp = in; CVector3 point = inTemp.point; point = (point - params.formulaPosition[0]).mod(params.formulaRepeat[0]); point = params.mRotFormulaRotation[0].RotateVector(point); point *= params.formulaScale[0]; inTemp.point = point; distance = CalculateDistanceSimple(params, fractals, inTemp, out, 0) / params.formulaScale[0]; CVector3 pointFractalized = inTemp.point; double reduceDisplacement = 1.0; pointFractalized = FractalizeTexture(inTemp.point, data, params, fractals, 0, &reduceDisplacement); distance = DisplacementMap(distance, pointFractalized, 0, data, reduceDisplacement); for (int i = 0; i < NUMBER_OF_FRACTALS - 1; i++) { if (fractals.GetFractal(i + 1)->formula != fractal::none) { sDistanceOut outTemp = *out; point = in.point - params.formulaPosition[i + 1]; point = point.mod(params.formulaRepeat[i + 1]); point = params.mRotFormulaRotation[i + 1].RotateVector(point); point *= params.formulaScale[i + 1]; inTemp.point = point; double distTemp = CalculateDistanceSimple(params, fractals, inTemp, &outTemp, i + 1) / params.formulaScale[i + 1]; CVector3 pointFractalized = inTemp.point; double reduceDisplacement = 1.0; pointFractalized = FractalizeTexture(inTemp.point, data, params, fractals, i + 1, &reduceDisplacement); distTemp = DisplacementMap(distTemp, pointFractalized, i + 1, data); const params::enumBooleanOperator boolOperator = params.booleanOperator[i]; switch (boolOperator) { case params::booleanOperatorOR: if (distTemp < distance) { outTemp.objectId = 1 + i; *out = outTemp; } distance = min(distTemp, distance); break; case params::booleanOperatorAND: if (distTemp > distance) { outTemp.objectId = 1 + i; *out = outTemp; } distance = max(distTemp, distance); break; case params::booleanOperatorSUB: { const double limit = 1.5; if (distance < in.detailSize) // if inside 1st { if (distTemp < in.detailSize * limit) // if inside 2nd { if (in.normalCalculationMode) { distance = in.detailSize * limit - distTemp; } else { distance = in.detailSize * limit; } } else // if outside of 2nd { if (in.detailSize * limit - distTemp > distance) { outTemp.objectId = 1 + i; *out = outTemp; } distance = max(in.detailSize * limit - distTemp, distance); if (distance < 0) distance = 0; } } else // if outside of 1st { // } break; } default: break; } } } } else { distance = CalculateDistanceSimple(params, fractals, in, out, -1); CVector3 pointFractalized = in.point; double reduceDisplacement = 1.0; pointFractalized = FractalizeTexture(in.point, data, params, fractals, -1, &reduceDisplacement); distance = DisplacementMap(distance, pointFractalized, 0, data, reduceDisplacement); } distance = min(distance, params.primitives.TotalDistance(in.point, distance, &out->objectId, data)); //**************************************************** if (params.limitsEnabled) { if (limitBoxDist < in.detailSize) { distance = max(distance, limitBoxDist); } } if (CheckNAN(distance)) // check if not a number { distance = 0.0; } const double distFromCamera = (in.point - params.camera).Length(); const double distanceLimitMin = params.viewDistanceMin - distFromCamera; if (distanceLimitMin > in.detailSize) { out->maxiter = false; out->objectId = 0; out->iters = 0; } distance = max(distance, distanceLimitMin); out->distance = distance; return distance; }