Logo by reallybigname - Contribute your own Logo!

END OF AN ERA, FRACTALFORUMS.COM IS CONTINUED ON FRACTALFORUMS.ORG

it was a great time but no longer maintainable by c.Kleinhuis contact him for any data retrieval,
thanks and see you perhaps in 10 years again

this forum will stay online for reference
News: Check out the originating "3d Mandelbulb" thread here
 
*
Welcome, Guest. Please login or register. July 27, 2021, 08:42:22 AM


Login with username, password and session length


The All New FractalForums is now in Public Beta Testing! Visit FractalForums.org and check it out!


Pages: 1 [2]   Go Down
  Print  
Share this topic on DiggShare this topic on FacebookShare this topic on GoogleShare this topic on RedditShare this topic on StumbleUponShare this topic on Twitter
Author Topic: Generalized Box Fold.  (Read 5274 times)
Description: Generalized conformal convex box fold algorithm.
0 Members and 1 Guest are viewing this topic.
fractower
Iterator
*
Posts: 173


« Reply #15 on: September 22, 2011, 04:56:03 PM »




This is a diff of the original fractal.cpp from mandelbulber 1.08 and the generalized box fold changes. The code essentially replaces the Tglad mandelbox box fold with the generalized fold. I had trouble implementing the "folding limit" function, so I have used this parameter to select between a number of polyhedron.

Folding limit               polyhedron
default                       tet
2                                cube
3                                oct
4                                dodeca
5                                turncated oct.

Disclaimer. The cube selection does not reproduce the original box fold. This points to a bug in either the theory or the implementation. However it produces some interesting fractals as is. I expect to find the bug when I try to implement the melting poly version suggested by Hobold.

I would be honored if Budda wants to integrate this into the mandelbulber, but he might want to wait a couple of days to see if I can fix the bug and melt some polys.

I did not realize that the code option compressed the file to a nice little window. Here is the entire fractower.cpp with the generalized box fold changes.

Code:
/********************************************************
 /                   MANDELBULBER                        *
 /                                                       *
 / author: Krzysztof Marczak                             *
 / contact: buddhi1980@gmail.com                         *
 / licence: GNU GPL                                      *
 ********************************************************/

/*
 * fractal.cpp
 *
 *  Created on: 2010-01-23
 *      Author: krzysztof
 */

#include "Render3D.h"
#include "interface.h"
#include "primitives.h"



inline CVector3 Cross(CVector3 A , CVector3 B){
  CVector3 C;
  C.x =  A.y*B.z - A.z*B.y;
  C.y = -A.x*B.z + A.z*B.x;
  C.z =  A.x*B.y - A.y*B.x;
  return (C);
}

// The box used by the generalized box fold is specified by a set
// of normalized unit vectors. Each vector is a normal that defines a plane.
// Xp dot N = foldingvalue.
#define sqrt_i3 .57735
CVector3 Nv_tet[] =  
{        
  { sqrt_i3, sqrt_i3,-sqrt_i3},
  { sqrt_i3,-sqrt_i3, sqrt_i3},
  {-sqrt_i3, sqrt_i3, sqrt_i3},
  {-sqrt_i3,-sqrt_i3,-sqrt_i3}
};

int sides_tet = 4;


CVector3 Nv_cube[] =  
{  
  { 1, 0, 0},
  {-1, 0, 0},
  { 0, 1, 0},
  { 0,-1, 0},
  { 0, 0, 1},
  { 0, 0,-1}
};

int sides_cube = 6;

CVector3 Nv_oct[] =  
{        
  { sqrt_i3, sqrt_i3,-sqrt_i3},
  { sqrt_i3,-sqrt_i3, sqrt_i3},
  {-sqrt_i3, sqrt_i3, sqrt_i3},
  {-sqrt_i3,-sqrt_i3,-sqrt_i3},
  { sqrt_i3, sqrt_i3, sqrt_i3},
  {-sqrt_i3,-sqrt_i3, sqrt_i3},
  {-sqrt_i3, sqrt_i3,-sqrt_i3},
  { sqrt_i3,-sqrt_i3,-sqrt_i3}
};

int sides_oct = 8;

CVector3 Nv_oct_cube[] =
  {        
    { sqrt_i3, sqrt_i3,-sqrt_i3},
    { sqrt_i3,-sqrt_i3, sqrt_i3},
    {-sqrt_i3, sqrt_i3, sqrt_i3},
    {-sqrt_i3,-sqrt_i3,-sqrt_i3},
    { sqrt_i3, sqrt_i3, sqrt_i3},
    {-sqrt_i3,-sqrt_i3, sqrt_i3},
    {-sqrt_i3, sqrt_i3,-sqrt_i3},
    { sqrt_i3,-sqrt_i3,-sqrt_i3},
  { 1, 0, 0},
    {-1, 0, 0},
    { 0, 1, 0},
    { 0,-1, 0},
    { 0, 0, 1},
    { 0, 0,-1}
  };
int sides_oct_cube = 14;


#define aa  ((1.0+sqrt(5.0))/2.0)
#define bb  (1.0/sqrt(aa*aa+1))

CVector3 Nv_dodeca[] =
  {
    { 0, bb, aa*bb},
    { 0, bb,-aa*bb},
    { 0,-bb, aa*bb},
    { 0,-bb,-aa*bb},
    { bb, aa*bb, 0},
    { bb,-aa*bb, 0},
    {-bb, aa*bb, 0},
    {-bb,-aa*bb, 0},
    { aa*bb, 0, bb},
    {-aa*bb, 0, bb},
    { aa*bb, 0,-bb},
    {-aa*bb, 0,-bb}
  };
int sides_dodeca = 12;


/**
 * Compute the fractal at the point, in one of the various modes
 *
 * Mode: normal: Returns distance
 * fake_ao: Returns minimum radius
 * colouring: Returns colour index
 * delta_DE1, delta_DE2: Returns radius
 */
template<int Mode>
double Compute(CVector3 z, const sFractal &par, int *iter_count)
{
int L;
double distance = 0;

double w = 0;
double constantw = 0;

CVector3 dz(1.0, 0.0, 0.0);
CVector3 one(1.0, 0.0, 0.0);
double r_dz = 1;
double ph_dz = 0;
double th_dz = 0;
double p = par.doubles.power; //mandelbulb power

CVector3 constant;

double fixedRadius = par.mandelbox.doubles.foldingSphericalFixed;
double fR2 = fixedRadius * fixedRadius;
double minRadius = par.mandelbox.doubles.foldingSphericalMin;
double mR2 = minRadius * minRadius;
double tglad_factor1 = fR2 / mR2;

double tgladDE = 1.0;

double scale = par.mandelbox.doubles.scale;

enumFractalFormula actualFormula = par.formula;
if (actualFormula == kaleidoscopic || actualFormula == menger_sponge)
tgladDE = 1.0;

double tgladColor = 1.0;

if (par.juliaMode)
{
constant = par.doubles.julia;
}
else
{
constant = z * par.doubles.constantFactor;
}

bool hybridEnabled = false;
if (actualFormula == hybrid) hybridEnabled = true;

double r = z.Length();

double min = 1e200;
for (L = 0; L < par.N; L++)
{
if (hybridEnabled)
{
int tempL = L;
if(tempL > (int)par.formulaSequence.size()-1) tempL = (int)par.formulaSequence.size()-1;
actualFormula = par.formulaSequence[tempL];
p = par.hybridPowerSequence[tempL];
scale = p;
}

if (par.IFS.foldingMode)
{
if (par.IFS.absX) z.x = fabs(z.x);
if (par.IFS.absY) z.y = fabs(z.y);
if (par.IFS.absZ) z.z = fabs(z.z);

for (int i = 0; i < IFS_VECTOR_COUNT; i++)
{
if (par.IFS.enabled[i])
{
z = par.IFS.rot[i].RotateVector(z);
double length = z.Dot(par.IFS.doubles.direction[i]);

if (length < par.IFS.doubles.distance[i])
{
z -= par.IFS.doubles.direction[i] * 2.0 * (length - par.IFS.doubles.distance[i]);
}

}
}

z = par.IFS.mainRot.RotateVector(z - par.IFS.doubles.offset) + par.IFS.doubles.offset;
z *= par.IFS.doubles.scale;
z -= par.IFS.doubles.offset * (par.IFS.doubles.scale - 1.0);

r = z.Length();
}

if (par.tgladFoldingMode)
{
if (z.x > par.doubles.foldingLimit)
{
z.x = par.doubles.foldingValue - z.x;
tgladColor *= 0.9;
}
else if (z.x < -par.doubles.foldingLimit)
{
z.x = -par.doubles.foldingValue - z.x;
tgladColor *= 0.9;
}
if (z.y > par.doubles.foldingLimit)
{
z.y = par.doubles.foldingValue - z.y;
tgladColor *= 0.9;
}
else if (z.y < -par.doubles.foldingLimit)
{
z.y = -par.doubles.foldingValue - z.y;
tgladColor *= 0.9;
}
if (z.z > par.doubles.foldingLimit)
{
z.z = par.doubles.foldingValue - z.z;
tgladColor *= 0.9;
}
else if (z.z < -par.doubles.foldingLimit)
{
z.z = -par.doubles.foldingValue - z.z;
tgladColor *= 0.9;
}
r = z.Length();
}

if (par.sphericalFoldingMode)
{
double fR2_2 = par.doubles.foldingSphericalFixed * par.doubles.foldingSphericalFixed;
double mR2_2 = par.doubles.foldingSphericalMin * par.doubles.foldingSphericalMin;
double r2_2 = r * r;
double tglad_factor1_2 = fR2_2 / mR2_2;

if (r2_2 < mR2_2)
{
z = z * tglad_factor1_2;
tgladDE *= tglad_factor1_2;
tgladColor += 1;
}
else if (r2_2 < fR2_2)
{
double tglad_factor2_2 = fR2_2 / r2_2;
z = z * tglad_factor2_2;
tgladDE *= tglad_factor2_2;
tgladColor += 10;
}
r = z.Length();
}

switch (actualFormula)
{
case trig_DE:
{
double r1 = pow(r, p - 1);
double r2 = r1 * r;
double th = z.GetAlfa();
double ph = -z.GetBeta();
if (Mode == 0)
{
double p_r1_rdz = p * r1 * r_dz;
double ph_phdz = (p - 1.0) * ph + ph_dz;
double th_thdz = (p - 1.0) * th + th_dz;
CVector3 rot(th_thdz, ph_phdz);
dz = rot * p_r1_rdz + one;
r_dz = dz.Length();
th_dz = dz.GetAlfa();
ph_dz = -dz.GetBeta();
}
CVector3 rot(p * th, p * ph);
z = rot * r2 + constant;
r = z.Length();
break;
}
case trig_optim:
{
//optimisation based on: http://www.fractalforums.com/mandelbulb-implementation/realtime-renderingoptimisations/
double th0 = asin(z.z / r);
double ph0 = atan2(z.y, z.x);
double rp = pow(r, p - 1.0);
double th = th0 * p;
double ph = ph0 * p;
double cth = cos(th);
r_dz = rp * r_dz * p + 1.0;
rp *= r;
z = CVector3(cth * cos(ph), cth * sin(ph), sin(th)) * rp + constant;
r = z.Length();
break;
}
case mandelbulb2:
{
double temp, tempR;
tempR = sqrt(z.x * z.x + z.y * z.y);
z *= (1.0 / tempR);
temp = z.x * z.x - z.y * z.y;
z.y = 2.0 * z.x * z.y;
z.x = temp;
z *= tempR;

tempR = sqrt(z.y * z.y + z.z * z.z);
z *= (1.0 / tempR);
temp = z.y * z.y - z.z * z.z;
z.z = 2.0 * z.y * z.z;
z.y = temp;
z *= tempR;

tempR = sqrt(z.x * z.x + z.z * z.z);
z *= (1.0 / tempR);
temp = z.x * z.x - z.z * z.z;
z.z = 2.0 * z.x * z.z;
z.x = temp;
z *= tempR;

z = z * r;
z += constant;
r = z.Length();
break;
}
case mandelbulb3:
{
double temp, tempR;

double sign = 1.0;
double sign2 = 1.0;

if (z.x < 0) sign2 = -1.0;
tempR = sqrt(z.x * z.x + z.y * z.y);
z *= (1.0 / tempR);
temp = z.x * z.x - z.y * z.y;
z.y = 2.0 * z.x * z.y;
z.x = temp;
z *= tempR;

if (z.x < 0) sign = -1.0;
tempR = sqrt(z.x * z.x + z.z * z.z);
z *= (1.0 / tempR);
temp = z.x * z.x - z.z * z.z;
z.z = 2.0 * z.x * z.z * sign2;
z.x = temp * sign;
z *= tempR;

z = z * r;
z += constant;
r = z.Length();
break;
}
case mandelbulb4:
{
double rp = pow(r, p - 1);

double angZ = atan2(z.y, z.x);
double angY = atan2(z.z, z.x);
double angX = atan2(z.z, z.y);

CRotationMatrix rotM;
rotM.RotateX(angX * (p - 1));
rotM.RotateY(angY * (p - 1));
rotM.RotateZ(angZ * (p - 1));

z = rotM.RotateVector(z) * rp + constant;
r = z.Length();
break;
}
case xenodreambuie:
{
double rp = pow(r, p);
double th = atan2(z.y, z.x);
double ph = acos(z.z / r);
if (ph > 0.5 * M_PI)
{
ph = M_PI - ph;
}
else if (ph < -0.5 * M_PI)
{
ph = -M_PI - ph;
}
z.x = rp * cos(th * p) * sin(ph * p);
z.y = rp * sin(th * p) * sin(ph * p);
z.z = rp * cos(ph * p);
z = z + constant;

r = z.Length();
break;
}
case fast_trig:
{
double x2 = z.x * z.x;
double y2 = z.y * z.y;
double z2 = z.z * z.z;
double temp = 1.0 - z2 / (x2 + y2);
double newx = (x2 - y2) * temp;
double newy = 2.0 * z.x * z.y * temp;
double newz = -2.0 * z.z * sqrt(x2 + y2);
z.x = newx + constant.x;
z.y = newy + constant.y;
z.z = newz + constant.z;
r = z.Length();
break;
}
case minus_fast_trig:
{
double x2 = z.x * z.x;
double y2 = z.y * z.y;
double z2 = z.z * z.z;
double temp = 1.0 - z2 / (x2 + y2);
double newx = (x2 - y2) * temp;
double newy = 2.0 * z.x * z.y * temp;
double newz = 2.0 * z.z * sqrt(x2 + y2);
z.x = newx + constant.x;
z.y = newy + constant.y;
z.z = newz + constant.z;
r = z.Length();
break;
}
case hypercomplex:
{
CVector3 newz(z.x * z.x - z.y * z.y - z.z * z.z - w * w, 2.0 * z.x * z.y - 2.0 * w * z.z, 2.0 * z.x * z.z - 2.0 * z.y * w);
double neww = 2.0 * z.x * w - 2.0 * z.y * z.z;
z = newz + constant;
w = neww;
r = sqrt(z.x * z.x + z.y * z.y + z.z * z.z + w * w);
break;
}
case quaternion:
{
CVector3 newz(z.x * z.x - z.y * z.y - z.z * z.z - w * w, 2.0 * z.x * z.y, 2.0 * z.x * z.z);
double neww = 2.0 * z.x * w;
z = newz + constant;
w = neww;
r = sqrt(z.x * z.x + z.y * z.y + z.z * z.z + w * w);
break;
}
case menger_sponge:
{
double temp;
z.x = fabs(z.x);
z.y = fabs(z.y);
z.z = fabs(z.z);
if (z.x - z.y < 0)
{
temp = z.y;
z.y = z.x;
z.x = temp;
}
if (z.x - z.z < 0)
{
temp = z.z;
z.z = z.x;
z.x = temp;
}
if (z.y - z.z < 0)
{
temp = z.z;
z.z = z.y;
z.y = temp;
}

if (Mode == colouring)
{
double length2 = z.Length();
if (length2 < min) min = length2;
}

z *= 3.0;

z.x -= 2.0;
z.y -= 2.0;
if (z.z > 1.0) z.z -= 2.0;
r = z.Length();
tgladDE *= 3.0;
break;
}
case tglad:
{
if (par.mandelbox.rotationsEnabled)
{
bool lockout = false;
z = par.mandelbox.rot[0][0].RotateVector(z);
if (z.x > par.mandelbox.doubles.foldingLimit)
{
z.x = par.mandelbox.doubles.foldingValue - z.x;
tgladColor += par.mandelbox.doubles.colorFactorX;
lockout = true;
}
z = par.mandelbox.rotinv[0][0].RotateVector(z);

z = par.mandelbox.rot[1][0].RotateVector(z);
if (!lockout && z.x < -par.mandelbox.doubles.foldingLimit)
{
z.x = -par.mandelbox.doubles.foldingValue - z.x;
tgladColor += par.mandelbox.doubles.colorFactorX;
}
z = par.mandelbox.rotinv[1][0].RotateVector(z);

lockout = false;
z = par.mandelbox.rot[0][1].RotateVector(z);
if (z.y > par.mandelbox.doubles.foldingLimit)
{
z.y = par.mandelbox.doubles.foldingValue - z.y;
tgladColor += par.mandelbox.doubles.colorFactorY;
lockout = true;
}
z = par.mandelbox.rotinv[0][1].RotateVector(z);

z = par.mandelbox.rot[1][1].RotateVector(z);
if (!lockout && z.y < -par.mandelbox.doubles.foldingLimit)
{
z.y = -par.mandelbox.doubles.foldingValue - z.y;
tgladColor += par.mandelbox.doubles.colorFactorY;
}
z = par.mandelbox.rotinv[1][1].RotateVector(z);

lockout = false;
z = par.mandelbox.rot[0][2].RotateVector(z);
if (z.z > par.mandelbox.doubles.foldingLimit)
{
z.z = par.mandelbox.doubles.foldingValue - z.z;
tgladColor += par.mandelbox.doubles.colorFactorZ;
lockout = true;
}
z = par.mandelbox.rotinv[0][2].RotateVector(z);

z = par.mandelbox.rot[1][2].RotateVector(z);
if (!lockout && z.z < -par.mandelbox.doubles.foldingLimit)
{
z.z = -par.mandelbox.doubles.foldingValue - z.z;
tgladColor += par.mandelbox.doubles.colorFactorZ;
}
z = par.mandelbox.rotinv[1][2].RotateVector(z);
}
else
{
 int i;
 CVector3 *Nv;
 int sides;
 // HACK HACK HACK. I high jacked the foldingLimit parameter to chose the poly type.
 // Do not try this at home.
 Nv = Nv_tet;
 sides = sides_tet;
 
 if(int(par.mandelbox.doubles.foldingLimit) == 2){
   Nv = Nv_cube;
   sides = sides_cube;
 }
 if(int(par.mandelbox.doubles.foldingLimit) == 3){
   Nv = Nv_oct;
   sides = sides_oct;
 }
 if(int(par.mandelbox.doubles.foldingLimit) == 4){
   Nv = Nv_dodeca;
   sides = sides_dodeca;
 }
 if(int(par.mandelbox.doubles.foldingLimit) == 5){
   Nv = Nv_oct_cube;
   sides = sides_oct_cube;
 }

 int sort[3];
 int tmp_sort;
 double Z_Dot_Nv[3];
 double tmp_Z_Dot_Nv;

 // Find the three closest normal vectors to z as defined by max dot product.
 sort[0] = 0;
 Z_Dot_Nv[0] = z.Dot(Nv[0]);
 sort[1]= 1;
 Z_Dot_Nv[1] = z.Dot(Nv[1]);
 sort[2]= 2;
 Z_Dot_Nv[2] = z.Dot(Nv[2]);

 if(Z_Dot_Nv[1]>Z_Dot_Nv[0]){
   tmp_sort =  sort[0];
   tmp_Z_Dot_Nv =  Z_Dot_Nv[0];
   sort[0] = sort[1];
   Z_Dot_Nv[0]=Z_Dot_Nv[1];
   sort[1]=tmp_sort;
   Z_Dot_Nv[1]= tmp_Z_Dot_Nv;
 }
 if(Z_Dot_Nv[2]>Z_Dot_Nv[1]){
   tmp_sort =  sort[1];
   tmp_Z_Dot_Nv =  Z_Dot_Nv[1];
   sort[1] = sort[2];
   Z_Dot_Nv[1]=Z_Dot_Nv[2];
   sort[2]=tmp_sort;
   Z_Dot_Nv[2]=tmp_Z_Dot_Nv;
 }
 if(Z_Dot_Nv[1]>Z_Dot_Nv[0]){
   tmp_sort =  sort[0];
   tmp_Z_Dot_Nv =  Z_Dot_Nv[0];
   sort[0] = sort[1];
   Z_Dot_Nv[0]=Z_Dot_Nv[1];
   sort[1]=tmp_sort;
   Z_Dot_Nv[1]= tmp_Z_Dot_Nv;
 }
 
 for(i=3;i<sides;i++){
    tmp_Z_Dot_Nv = z.Dot(Nv[i]);
    tmp_sort = i;
   if(tmp_Z_Dot_Nv>Z_Dot_Nv[2]){
     sort[2] = tmp_sort;
     Z_Dot_Nv[2]= tmp_Z_Dot_Nv;
     if(tmp_Z_Dot_Nv>Z_Dot_Nv[1]){
sort[2] = sort[1];
Z_Dot_Nv[2]=Z_Dot_Nv[1];
sort[1]=tmp_sort;
Z_Dot_Nv[1]= tmp_Z_Dot_Nv;
if(tmp_Z_Dot_Nv>Z_Dot_Nv[0]){
 sort[1] = sort[0];
 Z_Dot_Nv[1]=Z_Dot_Nv[0];
 sort[0]=tmp_sort;
 Z_Dot_Nv[0]= tmp_Z_Dot_Nv;
}
     }
   }
 }
 CVector3 Nv0=Nv[sort[0]];
 CVector3 Nv1=Nv[sort[1]];
 CVector3 Nv2=Nv[sort[2]];
 
 CVector3 new_z;
 double new_z_sqr;
 CVector3 Zm;
     
 // Assume z inside the poly and we are wasting our time.
 new_z = z;
 new_z_sqr = new_z.Dot(new_z);

 // Find reflection point to closest plain.
 Zm = z -  (Nv0 + Nv0)*(z.Dot(Nv0) -  par.mandelbox.doubles.foldingValue);
 if(new_z_sqr > Zm.Dot(Zm)){
   new_z = Zm;
   new_z_sqr = new_z.Dot(new_z);
   tgladColor += par.mandelbox.doubles.colorFactorX;
 }

 // Find rotation point to closest line.
 CVector3 T01, L01;
 L01 = Cross(Nv0,Nv1);
 L01 = L01 * (1.0/L01.Length());
 T01 = (Nv0+Nv1) * ( (par.mandelbox.doubles.foldingValue)/(1 + Nv0.Dot(Nv1)));
 CVector3 Zr;
 Zr = (T01 + L01 * z.Dot(L01)) * 2 - z;
 if(new_z_sqr > Zr.Dot(Zr)){
   new_z = Zr;
   new_z_sqr = new_z.Dot(new_z);
   tgladColor += par.mandelbox.doubles.colorFactorY;
 }

 // Find inversion point to closest vert.
 CVector3 Zi;
 double a;
 a = ((par.mandelbox.doubles.foldingValue)-T01.Dot(Nv2))/(L01.Dot(Nv2));
 Zi = (L01*a + T01) * 2 - z;
 if(new_z_sqr > Zi.Dot(Zi)){
   new_z = Zi;
   new_z_sqr = new_z.Dot(new_z);
   tgladColor += par.mandelbox.doubles.colorFactorZ;
 }
 z = new_z;
}

r = z.Length();
double r2 = r * r;

z += par.mandelbox.doubles.offset;

if (r2 < mR2)
{
z *= tglad_factor1;
tgladDE *= tglad_factor1;
tgladColor += par.mandelbox.doubles.colorFactorSp1;
}
else if (r2 < fR2)
{
double tglad_factor2 = fR2 / r2;
z *= tglad_factor2;
tgladDE *= tglad_factor2;
tgladColor += par.mandelbox.doubles.colorFactorSp2;
}

z -= par.mandelbox.doubles.offset;

z = par.mandelbox.mainRot.RotateVector(z);

z = z * scale + constant;
tgladDE = tgladDE*fabs(scale)+1.0;

r = z.Length();
break;
}
case smoothMandelbox:
{
double sm = par.mandelbox.doubles.sharpness;

double zk1 = SmoothConditionAGreaterB(z.x, par.mandelbox.doubles.foldingLimit,sm);
double zk2 = SmoothConditionALessB(z.x, -par.mandelbox.doubles.foldingLimit,sm);
z.x = z.x * (1.0 - zk1) + (par.mandelbox.doubles.foldingValue - z.x) * zk1;
z.x = z.x * (1.0 - zk2) + (-par.mandelbox.doubles.foldingValue - z.x) * zk2;
tgladColor += (zk1 + zk2) * par.mandelbox.doubles.colorFactorX;

double zk3 = SmoothConditionAGreaterB(z.y, par.mandelbox.doubles.foldingLimit,sm);
double zk4 = SmoothConditionALessB(z.y, -par.mandelbox.doubles.foldingLimit,sm);
z.y = z.y * (1.0 - zk3) + (par.mandelbox.doubles.foldingValue - z.y) * zk3;
z.y = z.y * (1.0 - zk4) + (-par.mandelbox.doubles.foldingValue - z.y) * zk4;
tgladColor += (zk3 + zk4) * par.mandelbox.doubles.colorFactorY;

double zk5 = SmoothConditionAGreaterB(z.z, par.mandelbox.doubles.foldingLimit,sm);
double zk6 = SmoothConditionALessB(z.z, -par.mandelbox.doubles.foldingLimit,sm);
z.z = z.z * (1.0 - zk5) + (par.mandelbox.doubles.foldingValue - z.z) * zk5;
z.z = z.z * (1.0 - zk6) + (-par.mandelbox.doubles.foldingValue - z.z) * zk6;
tgladColor += (zk5 + zk6) * par.mandelbox.doubles.colorFactorZ;

r = z.Length();
double r2 = r * r;
double tglad_factor2 = fR2 / r2;
double rk1 = SmoothConditionALessB(r2, mR2, sm);
double rk2 = SmoothConditionALessB(r2, fR2, sm);
double rk21 = (1.0 - rk1) * rk2;

z = z * (1.0 - rk1) + z * (tglad_factor1 * rk1);
z = z * (1.0 - rk21) + z * (tglad_factor2 * rk21);
tgladDE = tgladDE * (1.0 - rk1) + tgladDE * (tglad_factor1 * rk1);
tgladDE = tgladDE * (1.0 - rk21) + tgladDE * (tglad_factor2 * rk21);
tgladColor += rk1 * par.mandelbox.doubles.colorFactorSp1;
tgladColor += rk21 * par.mandelbox.doubles.colorFactorSp2;

z = par.mandelbox.mainRot.RotateVector(z);
z = z * scale + constant;

tgladDE = tgladDE * fabs(scale) + 1.0;
r = z.Length();
break;
}
case foldingIntPow2:
{
if (z.x > par.doubles.FoldingIntPowFoldFactor) z.x = par.doubles.FoldingIntPowFoldFactor * 2.0 - z.x;
else if (z.x < -par.doubles.FoldingIntPowFoldFactor) z.x = -par.doubles.FoldingIntPowFoldFactor * 2.0 - z.x;

if (z.y > par.doubles.FoldingIntPowFoldFactor) z.y = par.doubles.FoldingIntPowFoldFactor * 2.0 - z.y;
else if (z.y < -par.doubles.FoldingIntPowFoldFactor) z.y = -par.doubles.FoldingIntPowFoldFactor * 2.0 - z.y;

if (z.z > par.doubles.FoldingIntPowFoldFactor) z.z = par.doubles.FoldingIntPowFoldFactor * 2.0 - z.z;
else if (z.z < -par.doubles.FoldingIntPowFoldFactor) z.z = -par.doubles.FoldingIntPowFoldFactor * 2.0 - z.z;

r = z.Length();

double fR2_2 = 1.0;
double mR2_2 = 0.25;
double r2_2 = r * r;
double tglad_factor1_2 = fR2_2 / mR2_2;

if (r2_2 < mR2_2)
{
z = z * tglad_factor1_2;
}
else if (r2_2 < fR2_2)
{
double tglad_factor2_2 = fR2_2 / r2_2;
z = z * tglad_factor2_2;
}

z = z * 2.0;
double x2 = z.x * z.x;
double y2 = z.y * z.y;
double z2 = z.z * z.z;
double temp = 1.0 - z2 / (x2 + y2);
double newx = (x2 - y2) * temp;
double newy = 2.0 * z.x * z.y * temp;
double newz = -2.0 * z.z * sqrt(x2 + y2);
z.x = newx + constant.x;
z.y = newy + constant.y;
z.z = newz + constant.z;
z.z *= par.doubles.FoldingIntPowZfactor;
r = z.Length();
break;
}
case kaleidoscopic:
{
if (par.IFS.absX) z.x = fabs(z.x);
if (par.IFS.absY) z.y = fabs(z.y);
if (par.IFS.absZ) z.z = fabs(z.z);

for (int i = 0; i < IFS_VECTOR_COUNT; i++)
{
if (par.IFS.enabled[i])
{
z = par.IFS.rot[i].RotateVector(z);
double length = z.Dot(par.IFS.doubles.direction[i]);

if (length < par.IFS.doubles.distance[i])
{
z -= par.IFS.doubles.direction[i] * (2.0 * (length - par.IFS.doubles.distance[i]) * par.IFS.doubles.intensity[i]);
}

}
}
z = par.IFS.mainRot.RotateVector(z - par.IFS.doubles.offset) + par.IFS.doubles.offset;

if(par.IFS.doubles.edge.x > 0) z.x = par.IFS.doubles.edge.x - fabs(par.IFS.doubles.edge.x - z.x);
if(par.IFS.doubles.edge.y > 0) z.y = par.IFS.doubles.edge.y - fabs(par.IFS.doubles.edge.y - z.y);
if(par.IFS.doubles.edge.z > 0) z.z = par.IFS.doubles.edge.z - fabs(par.IFS.doubles.edge.z - z.z);

if (Mode == colouring)
{
double length2 = z.Length();
if (length2 < min) min = length2;
}

z *= par.IFS.doubles.scale;
if(par.IFS.mengerSpongeMode)
{
z.x -= par.IFS.doubles.offset.x * (par.IFS.doubles.scale - 1.0);
z.y -= par.IFS.doubles.offset.y * (par.IFS.doubles.scale - 1.0);
if (z.z > 0.5 * par.IFS.doubles.offset.z * (par.IFS.doubles.scale - 1.0)) z.z -= par.IFS.doubles.offset.z * (par.IFS.doubles.scale - 1.0);
}
else
{
z -= par.IFS.doubles.offset * (par.IFS.doubles.scale - 1.0);
}

tgladDE *= par.IFS.doubles.scale;
r = z.Length();

break;
}
case mandelboxVaryScale4D:
{
scale = scale + par.mandelbox.doubles.vary4D.scaleVary * (fabs(scale) - 1.0);
CVector3 oldz = z;
z.x = fabs(z.x + par.mandelbox.doubles.vary4D.fold) - fabs(z.x - par.mandelbox.doubles.vary4D.fold) - z.x;
z.y = fabs(z.y + par.mandelbox.doubles.vary4D.fold) - fabs(z.y - par.mandelbox.doubles.vary4D.fold) - z.y;
z.z = fabs(z.z + par.mandelbox.doubles.vary4D.fold) - fabs(z.z - par.mandelbox.doubles.vary4D.fold) - z.z;
w = fabs(w + par.mandelbox.doubles.vary4D.fold) - fabs(w - par.mandelbox.doubles.vary4D.fold) - w;
if(z.x != oldz.x) tgladColor += par.mandelbox.doubles.colorFactorX;
if(z.y != oldz.y) tgladColor += par.mandelbox.doubles.colorFactorY;
if(z.z != oldz.z) tgladColor += par.mandelbox.doubles.colorFactorZ;
double rr = pow(z.x * z.x + z.y * z.y + z.z * z.z + w * w, par.mandelbox.doubles.vary4D.rPower);
double m = scale;
if (rr < par.mandelbox.doubles.vary4D.minR * par.mandelbox.doubles.vary4D.minR)
{
m = scale / (par.mandelbox.doubles.vary4D.minR * par.mandelbox.doubles.vary4D.minR);
tgladColor += par.mandelbox.doubles.colorFactorSp1;
}
else if (rr < 1.0)
{
m = scale / rr;
tgladColor += par.mandelbox.doubles.colorFactorSp2;
}
z = z * m + constant;
w = w * m + par.mandelbox.doubles.vary4D.wadd;
tgladDE = tgladDE * fabs(m) + 1.0;
r = sqrt(z.x * z.x + z.y * z.y + z.z * z.z + w * w);
break;
}
case aexion:
{
if(L == 0)
{
double cx = fabs(constant.x + constant.y + constant.z) + par.doubles.cadd;
double cy = fabs(-constant.x - constant.y + constant.z) + par.doubles.cadd;
double cz = fabs(-constant.x + constant.y - constant.z) + par.doubles.cadd;
double cw = fabs(constant.x - constant.y - constant.z) + par.doubles.cadd;
constant.x = cx;
constant.y = cy;
constant.z = cz;
constantw = cw;
double tempx = fabs(z.x + z.y + z.z) + par.doubles.cadd;
double tempy = fabs(-z.x - z.y + z.z) + par.doubles.cadd;
double tempz = fabs(-z.x + z.y - z.z) + par.doubles.cadd;
double tempw = fabs(z.x - z.y - z.z) + par.doubles.cadd;
z.x = tempx;
z.y = tempy;
z.z = tempz;
w = tempw;
}
double tempx = z.x * z.x - z.y * z.y + 2.0 * w * z.z + constant.x;
double tempy = z.y * z.y - z.x * z.x + 2.0 * w * z.z + constant.y;
double tempz = z.z * z.z - w * w + 2.0 * z.x * z.y + constant.z;
double tempw = w * w - z.z * z.z + 2.0 * z.x * z.y + constantw;
z.x = tempx;
z.y = tempy;
z.z = tempz;
w = tempw;
r = sqrt(z.x * z.x + z.y * z.y + z.z * z.z + w * w);
break;
}
case benesi:
{
double r1 = z.y*z.y + z.z*z.z;
double newx = 0;
if(constant.x < 0 || z.x < sqrt(r1))
{
newx = z.x*z.x - r1;
}
else
{
newx = -z.x*z.x + r1;
}
r1 = - 1.0/sqrt(r1) * 2.0 * fabs(z.x);
double newy = r1 * (z.y*z.y - z.z*z.z);
double newz = r1 * 2.0 * z.y * z.z;

z.x = newx + constant.x;
z.y = newy + constant.y;
z.z = newz + constant.z;

r = z.Length();
break;
}
case bristorbrot:
{
double newx = z.x*z.x - z.y*z.y - z.z*z.z;
double newy = z.y * (2.0 * z.x - z.z);
double newz = z.z * (2.0 * z.x + z.y);

z.x = newx + constant.x;
z.y = newy + constant.y;
z.z = newz + constant.z;

r = z.Length();
break;
}
case invertX:
{
z.x = z.x >= 0.0 ? z.x*z.x/(fabs(z.x) + p) : -z.x*z.x/(fabs(z.x) + p);
r = z.Length();
break;
}
case invertY:
{
z.y = z.y >= 0.0 ? z.y*z.y/(fabs(z.y) + p) : -z.y*z.y/(fabs(z.y) + p);
r = z.Length();
break;
}
case invertZ:
{
z.z = z.z >= 0.0 ? z.z*z.z/(fabs(z.z) + p) : -z.z*z.z/(fabs(z.z) + p);
r = z.Length();
break;
}
case invertR:
{
double rInv = r*r/(r + p);
z.x = z.x / r * rInv;
z.y = z.y / r * rInv;
z.z = z.z / r * rInv;
r = z.Length();
break;
}
case sphericalFold:
{
double rr = r*r;
double pp = p*p;
if (rr < pp)
{
z.x = 1.0 / pp;
z.y = 1.0 / pp;
z.z = 1.0 / pp;
}
else if (rr < pp*4.0)
{
z.x = 1.0 / rr;
z.y = 1.0 / rr;
z.z = 1.0 / rr;
}
r = z.Length();
break;
}
case powXYZ:
{
z.x = z.x >= 0 ? pow(z.x,p) : -pow(-z.x,p);
z.y = z.y >= 0 ? pow(z.y,p) : -pow(-z.y,p);
z.z = z.z >= 0 ? pow(z.z,p) : -pow(-z.z,p);
r = z.Length();
break;
}
case scaleX:
{
z.x = z.x * p;
r = z.Length();
break;
}
case scaleY:
{
z.y = z.y * p;
r = z.Length();
break;
}
case scaleZ:
{
z.z = z.z * p;
r = z.Length();
break;
}
case offsetX:
{
z.x = z.x + p;
r = z.Length();
break;
}
case offsetY:
{
z.y = z.y + p;
r = z.Length();
break;
}
case offsetZ:
{
z.z = z.z + p;
r = z.Length();
break;
}
case angleMultiplyX:
{
double angle = atan2(z.z,z.y)*p;
double tempR = sqrt(z.z*z.z + z.y*z.y);
z.y = tempR * cos(angle);
z.z = tempR * sin(angle);
r = z.Length();
break;
}
case angleMultiplyY:
{
double angle = atan2(z.z,z.x)*p;
double tempR = sqrt(z.z*z.z + z.x*z.x);
z.x = tempR * cos(angle);
z.z = tempR * sin(angle);
r = z.Length();
break;
}
case angleMultiplyZ:
{
double angle = atan2(z.y,z.x)*p;
double tempR = sqrt(z.x*z.x + z.y*z.y);
z.x = tempR * cos(angle);
z.y = tempR * sin(angle);
r = z.Length();
break;
}
case hybrid:
break;
case none:
break;
}

//************************** iteration terminate conditions *****************
if (Mode == deltaDE1)
{
if (r > 1e10)
break;
}
else if (Mode == deltaDE2)
{
if (L == *iter_count)
break;
}

if (actualFormula == menger_sponge || actualFormula == kaleidoscopic)
{
if (r > 1000)
{
distance = (r - 2.0) / tgladDE;
break;
}
}
else if (actualFormula == tglad || actualFormula == smoothMandelbox || actualFormula == mandelboxVaryScale4D)
{
if (r > 1024)
{
distance = r / fabs(tgladDE);
break;
}
}
else
{
if (Mode == normal) //condition for all other trigonometric and hypercomplex fractals
{
if (r > 1e2)
{
distance = 0.5 * r * log(r) / r_dz;
break;
}
}
else if (Mode == fake_AO) //mode 2
{
if (r < min) min = r;
if (r > 1e15)
{
distance = min;
break;
}
}
else if (Mode == colouring) //mode 1
{
distance = z.Length();
if (distance < min) min = distance;
if (distance > 1e15)
{
distance = min;
break;
}
}
}
}

//************ return values *****************
N_counter += L + 1;
Loop_counter++;

if (L < 64)
histogram[L]++;
else
histogram[63]++;

if (iter_count != NULL)
*iter_count = L;

if (Mode == normal)
{
if (L == par.N)
distance = 0;
return distance;
}

if (Mode == deltaDE1 || Mode == deltaDE2)
return r;

if (Mode == fake_AO)
return distance;

if (Mode == colouring)
{
if (par.formula == hybrid)
{
if (min > 100)
min = 100;
if (distance > 20)
distance = 20;
if (tgladColor > 1000)
tgladColor = 1000;

return distance * 5000.0 + tgladColor * 100.0 + min * 1000.0;
}
else if (actualFormula == tglad || actualFormula == smoothMandelbox || actualFormula == mandelboxVaryScale4D)
return tgladColor * 100.0 + z.Length()*par.mandelbox.doubles.colorFactorR;
else if (actualFormula == kaleidoscopic || actualFormula == menger_sponge)
return min * 1000.0;
else
return distance * 5000.0;
}
}

//******************* Calculate distance *******************8

double CalculateDistance(CVector3 point, sFractal &params, bool *max_iter)
{
int L;
double distance;
params.specialColour = 0;

if (params.limits_enabled)
{
bool limit = false;
double distance_a = 0;
double distance_b = 0;
double distance_c = 0;

if (point.x < params.doubles.amin)
{
distance_a = fabs(params.doubles.amin - point.x) + params.doubles.detailSize;
limit = true;
}
if (point.x > params.doubles.amax)
{
distance_a = fabs(params.doubles.amax - point.x) + params.doubles.detailSize;
limit = true;
}

if (point.y < params.doubles.bmin)
{
distance_a = fabs(params.doubles.bmin - point.y) + params.doubles.detailSize;
limit = true;
}
if (point.y > params.doubles.bmax)
{
distance_b = fabs(params.doubles.bmax - point.y) + params.doubles.detailSize;
limit = true;
}

if (point.z < params.doubles.cmin)
{
distance_c = fabs(params.doubles.cmin - point.z) + params.doubles.detailSize;
limit = true;
}
if (point.z > params.doubles.cmax)
{
distance_c = fabs(params.doubles.cmax - point.z) + params.doubles.detailSize;
limit = true;
}

if (limit)
{
if (max_iter != NULL)
*max_iter = false;
distance = dMax(distance_a, distance_b, distance_c);
return distance;
}
}

if (params.analitycDE)
{
distance = Compute<normal>(point, params, &L);
if (max_iter != NULL)
{
if (L == params.N)
*max_iter = true;
else
*max_iter = false;
}

if (L < params.minN && distance < params.doubles.detailSize)
distance = params.doubles.detailSize;

if (params.interiorMode)
{
if (distance < 0.5 * params.doubles.detailSize || L == params.N)
{
distance = params.doubles.detailSize;
if (max_iter != NULL)
*max_iter = false;
}
}
}
else
{
double deltaDE = 1e-10;

double r = Compute<deltaDE1>(point, params, &L);
int retval = L;

point.x += deltaDE;
point.y += 0;
point.z += 0;
double r2 = Compute<deltaDE2>(point, params, &L);
double dr1 = fabs(r2 - r) / deltaDE;

point.x -= deltaDE;
point.y += deltaDE;
point.z += 0;
r2 = Compute<deltaDE2>(point, params, &L);
double dr2 = fabs(r2 - r) / deltaDE;

point.x += 0;
point.y -= deltaDE;
point.z += deltaDE;
r2 = Compute<deltaDE2>(point, params, &L);
double dr3 = fabs(r2 - r) / deltaDE;

double dr = sqrt(dr1 * dr1 + dr2 * dr2 + dr3 * dr3);

if(params.linearDEmode)
{
distance = 0.5 * r / dr;
}
else
{
distance = 0.5 * r * log(r) / dr;
}

if (retval == params.N)
{
if (max_iter != NULL)
*max_iter = true;
distance = 0;
}
else if (max_iter != NULL)
*max_iter = false;

if (L < params.minN && distance < params.doubles.detailSize)
distance = params.doubles.detailSize;

if (params.interiorMode)
{
if (distance < 0.5 * params.doubles.detailSize || retval == 256)
{
distance = params.doubles.detailSize;
if (max_iter != NULL)
*max_iter = false;
}
}
}

//plane
if (params.primitives.planeEnable)
{
double planeDistance = PrimitivePlane(point, params.doubles.primitives.planeCentre, params.doubles.primitives.planeNormal);
if(planeDistance < distance) params.specialColour = 253;
distance = (planeDistance < distance) ? planeDistance : distance;

}

//box
if (params.primitives.boxEnable)
{
double boxDistance = PrimitiveBox(point, params.doubles.primitives.boxCentre, params.doubles.primitives.boxSize);
if(boxDistance < distance) params.specialColour = 252;
distance = (boxDistance < distance) ? boxDistance : distance;
}

//inverted box
if (params.primitives.invertedBoxEnable)
{
double boxDistance = PrimitiveInvertedBox(point, params.doubles.primitives.invertedBoxCentre, params.doubles.primitives.invertedBoxSize);
if(boxDistance < distance) params.specialColour = 251;
distance = (boxDistance < distance) ? boxDistance : distance;
}

//sphere
if (params.primitives.sphereEnable)
{
double sphereDistance = PrimitiveSphere(point, params.doubles.primitives.sphereCentre, params.doubles.primitives.sphereRadius);
if(sphereDistance < distance) params.specialColour = 250;
distance = (sphereDistance < distance) ? sphereDistance : distance;
}

//invertedSphere
if (params.primitives.invertedSphereEnable)
{
double sphereDistance = PrimitiveInvertedSphere(point, params.doubles.primitives.invertedSphereCentre, params.doubles.primitives.invertedSphereRadius);
if(sphereDistance < distance) params.specialColour = 249;
distance = (sphereDistance < distance) ? sphereDistance : distance;
}

//water
if (params.primitives.waterEnable)
{
double waterDistance = PrimitiveWater(point, params.doubles.primitives.waterHeight, params.doubles.primitives.waterAmplitude,
params.doubles.primitives.waterLength, params.doubles.primitives.waterRotation, params.primitives.waterIterations);
if(waterDistance < distance) params.specialColour = 248;
distance = (waterDistance < distance) ? waterDistance : distance;
}

if (distance < 0) distance = 0;

return distance;
}

// force template instantiation
template double Compute<normal>(CVector3, const sFractal&, int*);
template double Compute<colouring>(CVector3, const sFractal&, int*);
template double Compute<fake_AO>(CVector3, const sFractal&, int*);
template double Compute<deltaDE1>(CVector3, const sFractal&, int*);
template double Compute<deltaDE2>(CVector3, const sFractal&, int*);
« Last Edit: September 22, 2011, 04:59:55 PM by fractower » Logged
DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #16 on: September 22, 2011, 04:58:52 PM »

It looks far too complicated to translate into raw assembly code for me undecided cry I pass the ball tongue stuck out
Logged

No sweat, guardian of wisdom!
marius
Fractal Lover
**
Posts: 206


« Reply #17 on: September 22, 2011, 07:23:39 PM »

It looks far too complicated to translate into raw assembly code for me undecided cry I pass the ball tongue stuck out

With the right incantations about position independence and calling conventions, and discipline regarding globals, you can write the m3b formulae in C, no?
Logged
Aexion
Conqueror
*******
Posts: 116


The Fractal Hermit


WWW
« Reply #18 on: September 22, 2011, 08:42:26 PM »

None was interested (on implementing it), but still here are the multidimensional box fold: smiley
(ok,ok, they where overly complex.. but it was a nice try!
also, there are other shapes, such as donuts and diamonds)

http://www.fractalforums.com/3d-fractal-generation/platonic-dimensions/





« Last Edit: September 22, 2011, 08:54:14 PM by Aexion » Logged

Fractals all the way..
Incendia for 3D Fractals
Aural for Musical Fractals
DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #19 on: September 22, 2011, 09:15:34 PM »

Your formula has a different look from this one wink

And for the question to me; no! It is too time consuming passing to C code to assembly. Anyway if you think it is simple... I will pass u the addresses and you cqn try yourself wink
Logged

No sweat, guardian of wisdom!
Aexion
Conqueror
*******
Posts: 116


The Fractal Hermit


WWW
« Reply #20 on: September 22, 2011, 11:44:31 PM »

Your formula has a different look from this one wink


Ok.ok.. I know.. I just was mentioning them (my formulas are always a mess smiley )..
Anyways, if you have nothing to do, you can just play with this GyroidFold formula, made of nested Gyroids, complete with
my best wishes to the user:

Code:
bool BGyroidfold(double x, double y, double z,int miter){

  const double ctx =x;
  const double cty =y;
  const double ctz =z;

x=0;
y=0;
z=0;

for(unsigned char Counter=0;Counter<miter;Counter++){
if(x>1)x=2-x;
else
if(x<-1)x=-2-x;
if(y>1)y=2-y;
else
if(y<-1)y=-2-y;
if(z>1)z=2-z;
else
if(z<-1)z=-2-z;
const float rw=(cos(x) * sin(y) + cos(y) * sin(z) + cos(z) * sin(x))*3.141592653;//Gyroid
const float vm=fabs(rw);
        if(vm<0.5){
        x=x*4;
        y=y*4;
        z=z*4;
       } else
       if(vm<1){
       const float vsq=vm*vm;
       x/=vsq;
       y/=vsq;
       z/=vsq;
      }
      x=x*2+ctx;
      y=y*2+cty;
      z=z*2+ctz;
      if ((x*x+y*y+z*z)>3600) break;
      }
if((x*x+y*y+z*z)<3600)
return true;
else
return false;
}

 devil
Logged

Fractals all the way..
Incendia for 3D Fractals
Aural for Musical Fractals
marius
Fractal Lover
**
Posts: 206


« Reply #21 on: September 23, 2011, 01:05:22 AM »

And for the question to me; no! It is too time consuming passing to C code to assembly. Anyway if you think it is simple... I will pass u the addresses and you cqn try yourself wink

darkbeam, how about something like:
Code:
// From fractalforums.com/mandelbulb-3d/asking-permission/msg27618/#msg27618
__attribute__((packed)) struct TIteration3Dext {
double J4,Rold,RStopD,x,y,z,w;//: Double;   // use with neg indizes before C1
double C1, C2, C3;//: Double;     //
double J1, J2, J3;//: Double;     //+24   these are the constants for adding. (x0, y0, z0) or (Cx, Cy, Cz).  w0 is J4 (-56)
void*  PVar;//:       Pointer;    //+48   the actual formulas adress of constants and vars
float  SmoothItD;//:  Single;     //+52
double Rout;//:       Double;     //+56   the square of the vector length, can be used as input
int    ItResultI;//:  Integer;    //+64
int    maxIt;//:      Integer;    //+68
float  RStop;//:      Single;     //+72
int    nHybrid[5];//:    array[0..5] of Integer;  //+76 Hybrid counts or single weights in interpolhybrid
void*  fHPVar[5];//:     array[0..5] of Pointer;  //+100 pointer to constants+vars, PVars-8=0.5, dOption values below -8
void*  fHybrid[5];//:    array[0..5] of ThybridIteration2; //+124   adresses of formulas
int    CalcSIT;//:    LongBool;   //+148
int    DoJulia;//:    LongBool;   //+152
float  LNRStop;//:    Single;     //+156
int    DEoption;//:   Integer;    //+160
float  fHln[5];//:       array[0..5] of Single;  //+164  for SmoothIts
int    iRepeatFrom;//: Integer;   //+188
double OTrap;//:      Double;     //+192
double VaryScale;//:  Double;     //+200    to use in vary by its
int    bFirstIt;//:   Integer;    //+208    used also as iteration count, is set to 0 on it-start
int    bTmp;//:       Integer;    //+212    tmpBuf, free of use.
double Dfree1;//:     Double;     //+216
double Dfree2;//:     Double;     //+224
double Deriv1;//:     Double;     //+232    for 4D first deriv or as full derivs
double Deriv2;//:     Double;     //+240
double Deriv3;//:     Double;     //+248
double SMatrix4[4][4];//:   TSMatrix4;  //+256
};

// fastcall is not quite delphi fastcall.
// first two args are ok, third is in ecx in delphi, on stack here.
void __attribute__((fastcall)) formula(
             double* x,      // [eax]
             double* y,      // [edx]
             double* arg,    // [ebp+8], points to TIteration3Dext.C1
             void* dummy     // so we end w/ ret 8 as delphi expects
             ) {
  // Compute ptr to proper start of TIteration3Dext struct.
  struct TIteration3Dext* cfg = (struct TIteration3Dext*)(arg-7);

  // Read / write some fields as demonstration.. not a real formula ;-)
  double r = cfg->x + cfg->y - cfg->z * cfg->w;
  cfg->Deriv1 = r;
}

compile with 'gcc -c -Os -m32'. The objdump -D of the generated code shows:
Code:
Disassembly of section .text:

00000000 <formula>:
   0: 55                    push   %ebp
   1: 89 e5                mov    %esp,%ebp
   3: 8b 45 08              mov    0x8(%ebp),%eax
   6: 83 e8 38              sub    $0x38,%eax
   9: dd 40 18              fldl   0x18(%eax)
   c: dc 40 20              faddl  0x20(%eax)
   f: dd 40 28              fldl   0x28(%eax)
  12: dc 48 30              fmull  0x30(%eax)
  15: de e9                fsubrp %st,%st(1)
  17: dd 98 10 01 00 00    fstpl  0x110(%eax)
  1d: 5d                    pop    %ebp
  1e: c2 08 00              ret    $0x8

That should be fairly compatible with m3b's expectations, eyeballing suggests.
Some definitions need polishing and further explanations (perhaps Jesse can chime in, but you probably know the details already).
But after that this should make it a whole lot easier to code m3f files than in asm. And you get compiler optimizations for free grin
Logged
DarkBeam
Global Moderator
Fractal Senior
******
Posts: 2512


Fragments of the fractal -like the tip of it


« Reply #22 on: September 23, 2011, 09:04:46 AM »

Never really tried that way shocked ... It can be a good idea ty!
Luca
Logged

No sweat, guardian of wisdom!
fractower
Iterator
*
Posts: 173


« Reply #23 on: September 23, 2011, 09:41:59 AM »

I was able to get the melting option to work.

Logged
Jesse
Download Section
Fractal Schemer
*
Posts: 1013


« Reply #24 on: September 23, 2011, 09:40:43 PM »

That should be fairly compatible with m3b's expectations, eyeballing suggests.
Some definitions need polishing and further explanations (perhaps Jesse can chime in, but you probably know the details already).
But after that this should make it a whole lot easier to code m3f files than in asm. And you get compiler optimizations for free grin

Thx, i added a C compatible struct in the message you mentioned:
www.fractalforums.com/mandelbulb-3d/asking-permission/msg27618/#msg27618

But you always have to check whether calls or absolute addresses are used by the compiler.
For constants and user variables you could also do the trick like in "struct TIteration3Dext* cfg = .."
with the PVar pointer.

Luca, hijacking is stearing the thread in a not intended direction like m3d intern struct code in a generalized box fold topic thread  wink
(just because you wanted to know this in another thread, you are not guilty or so!)
Logged
knighty
Fractal Iambus
***
Posts: 819


« Reply #25 on: September 23, 2011, 11:31:57 PM »

Nice sequence fractower. A video?

Logged
Pages: 1 [2]   Go Down
  Print  
 
Jump to:  

Related Topics
Subject Started by Replies Views Last post
Generalized Box folds. Mandelbulber Gallery fractower 0 795 Last post September 21, 2011, 08:47:33 AM
by fractower
Generalized Apollonius: random ellipsoid packings 3D Fractal Generation hobold 3 1554 Last post February 04, 2013, 07:28:29 PM
by knighty
3-fold symmetry Still Frame Kalles Fraktaler 0 744 Last post May 08, 2014, 05:02:44 PM
by Kalles Fraktaler
Generalized shape inversion applied to the Mandelbox Amazing Box, Amazing Surf and variations « 1 2 » CozyG 17 3010 Last post August 12, 2017, 02:45:07 PM
by Alef
Generalized Fold Box Mesh Images Showcase (Rate My Fractal) Buddhi 0 560 Last post November 09, 2017, 08:32:59 PM
by Buddhi

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2015, Simple Machines

Valid XHTML 1.0! Valid CSS! Dilber MC Theme by HarzeM
Page created in 0.176 seconds with 25 queries. (Pretty URLs adds 0.011s, 2q)