MandelBrot set 3D Demo

Everything related to 3D programming
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

MandelBrot set 3D Demo

Post by applePi »

this is a demo of mandelbrot set 3D, also Julia set 3D. it is a translation from a code i attach below which contains OpenGL code, the size of code in purebasic ogre are much less and concise and straight forward. it is a real nightmare to try it in OpenGL. this is the new feature in the new version of PureBasic v 5.10 which introduce the ability to draw lists of points in 3D the easiest way without tedious previous preparations.
this demo will show Mandelbrot set 3D as a default, if you want Julia 3D change line 34 from mand = 1 to mand = 0, the time of calculation of 3 million points is 15 seconds on my slow pc, if you want less time reduce iterations to 1 million or less in line 136
iterations = 3000000
the function RandF is from kenmo from http://www.purebasic.fr/english/viewtop ... 13&t=45652.
i have'nt optimized the code so you can make more exploration and optimization
save the file in Examples\3D and use the keys described on the title bar to rotate/stop , zoom+/- , up/down.

Image

Image

ref: a great site for 3d fractals http://www.skytopia.com/project/fractal/mandelbulb.html
PS: the purebasic essential code are from MeshManual2.pb
PureBasic v5.10 code

Code: Select all

Enumeration
   #MESH
   #LIGHT
   #CAMERA_ONE
   #BUTTON
   #mainwin
 EndEnumeration
 ;constants for the biomorph function
 #constreal = 0.5 
  #constimag = 0 
  #screenheight = 500
  #screenwidth = 500
  
Global.f dx, dy, x, y, z
Global wd, ht, i, count, n, iter
Global.f w, leng, tx, ty, tz, tem
Global.f cr, ci, cj, ck, wk, inc, distance
Global mand, zval
Global.f angle
Define.f red, green, blue
;zval = 1 shows entire set
;zval = 0 cuts set in half
;zval = 0 is an interesting effect
wd = 500
ht = 500
;defines the shape of the Julia Set
cr = -0.200
ci = 0.800
cj = 0.000
ck = 0.000
wk = 0.000
;mand = 0 is Julia Set
;mand = 1 is Mandelbrot 3D
mand = 1
;zval = 1 shows entire set
;zval = 0 cuts set in half
;zval = 0 is an interesting effect
zval = 1
iter = 5
inc = 5 
;#quat = 1
zval = 1
iter = 5
inc = 5 
Procedure.f RandF(Min.f, Max.f, Resolution.i = 10000)
  ProcedureReturn (Min + (Max - Min) * Random(Resolution) / Resolution)
EndProcedure

Quit.b = #False
rot.l=1 :stopFlag = 1
xs.f = 0.3:ys.f = 0.3:zs.f = 0.3
x.f: y.f :z.f: x0.f: y0.f=1 :z0.f
rotx.f:roty.f=1:rotz.f :rotx0.f: roty0.f: rotz0.f
up.f = 2.2: depth.f=0

ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "PgUp PgD scale mesh..Arrows for rotation, space: stop/rotate,  QA Up/Down, WS far/near", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(#BUTTON, 0, DesktopHeight(0)-60, 60, 30, "rotate/stop") 

;Initialize environment
InitEngine3D()
InitSprite()
OpenWindowedScreen(WindowID(#mainwin), 0, 0, DesktopWidth(0), DesktopHeight(0)-70, 0, 0, 0)
WorldShadows(#PB_Shadow_Additive)

InitKeyboard()
SetFrameRate(60)

Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)

CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))

CreateCamera(#CAMERA_ONE, 0, 0, 100, 100)
MoveCamera(#CAMERA_ONE, 0, 4, 9)
CameraLookAt(#CAMERA_ONE, 0, 2, 0)

RotateCamera(#CAMERA_ONE, -15, 0, 0)
EndIf

SetActiveGadget(#BUTTON)
;SkyDome("clouds.jpg", 100) ;for blue color background

;- Mesh Stars
CreateMaterial(0, LoadTexture(0, "White.jpg"))
DisableMaterialLighting(0, #True)
CreateMesh(1, #PB_Mesh_PointList, #False)
;CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Static )

SetMeshMaterial(1, MaterialID(0))
Global Stars = CreateNode(#PB_Any)
AttachNodeObject(Stars, MeshID(1))

Procedure.f calcleng( x.f,  y.f,  z.f)
    w.f: kr.f: ki.f: kj.f: kk.f
    w = wk
    n = 0
    If mand = 1  ;full Mandelbrot set
        kr = x
        ki = y
        kj = z
        kk = 0
    Else                ;else draw Julia Set
        kr = cr
        ki = ci
        kj = cj
        kk = ck
    EndIf
    
    While n < iter
        tem = x+x
        x = x*x-y*y-z*z-w*w+kr
        y = tem*y + ki
        z = tem*z + kj
        w = tem*w + kk
        
        n+1
        distance = x*x+y*y+z*z+w*w
        
        If distance > 4 
          n = iter
        EndIf
        
    Wend
        
    ;Return distance
    ProcedureReturn distance
  
EndProcedure

  

Procedure calcit()
    zz.f
    foo.l
    iterations = 3000000
    count = 0
    
    If zval = 0
        zz = 2.0
    Else
        zz = 4.0
    EndIf
      
      For foo = 0 To iterations
          ;x.f = RandF(0, 1)
          ;y.f = RandF(0, 1)
          x.f = RandF(-2, 2)
          y.f = RandF(-2, 2)
          
          z.f = zz*RandF(0, 1) -2.0
          
          ;calls the quaternion calculation
          leng.f = calcleng(x,y,z)
          
          If leng < 4 
              MeshVertexPosition(x, y, z)
              red = (x+Cos(15*leng))*255
              green = (y+Sin(1-leng)*Cos(5*leng))*255
              blue = (z+Sin(0.75*leng))*255
              If red < 0 : red = 0 : EndIf
              If green < 0 : green = 0 : EndIf
              If blue < 0 : blue = 0 : EndIf
              ;If red > 255 : red = red-255 : EndIf
              ;If green > 255 : green = green-255 : EndIf
              ;If blue > 255 : blue = blue-255 : EndIf
              
              ;MeshVertexColor(RGBA(red,green,blue,0))
              MeshVertexColor(RGB(red,green,blue))
                           
          EndIf
          
        Next 
        FinishMesh(#False)
        NormalizeMesh(1)
      
EndProcedure


calcit()  ; calling the mandel 3D or julia generator function

;Main loop
Repeat
  Event = WindowEvent()
  If Event = #PB_Event_Gadget
    Select EventGadget()
      Case #BUTTON
        If rot = 0
          rot = 1
          rotx= rotx0:roty=roty0:rotz=rotz0 ; restore rotation status
          stopFlag = 1
          
        Else
          rot = 0
          rotx0= rotx:roty0=roty:rotz0=rotz ;back up rotation status
          rotx=0:roty=0:rotz=0
          stopFlag = 0
          
        EndIf
                    
    EndSelect
  EndIf 
  If stopFlag=1
    x + rotx
    y + roty
    z + rotz
  EndIf
  
   RotateNode(Stars, x, y, z)
   
   RenderWorld()
   FlipBuffers()

  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Up)  ; rotate left
    rotx=1:roty=0:rotz=0
    rotx0 = rotx: roty0 = roty :rotz0 = rotz
    x + rotx
    y + roty
    z + rotz
    stopFlag=0
    rot = 0
  ElseIf KeyboardPushed(#PB_Key_Down) ; rotate right
    rotx=-1:roty=0:rotz=0
    rotx0 = rotx: roty0 = roty :rotz0 = rotz
    x + rotx
    y + roty
    z + rotz
    stopFlag=0
    rot = 0
  ElseIf KeyboardPushed(#PB_Key_Right)   ; rotate up
    rotx=0:roty=1:rotz=0
    rotx0 = rotx: roty0 = roty :rotz0 = rotz
    x + rotx
    y + roty
    z + rotz
    stopFlag=0
    rot = 0
  ElseIf KeyboardPushed(#PB_Key_Left) ; rotate down
    rotx=0:roty=-1:rotz=0 
    rotx0 = rotx: roty0 = roty :rotz0 = rotz
    x + rotx
    y + roty
    z + rotz
    stopFlag=0
    rot = 0
  EndIf 
  
  If KeyboardPushed(#PB_Key_PageUp) ; scale up model
    xs.f = 1.1:ys.f = 1.1:zs.f = 1.1
    ScaleNode(Stars,xs,ys,zs)
    
  ElseIf KeyboardPushed(#PB_Key_PageDown) ; scale down model
    xs = 0.9:ys = 0.9:zs= 0.9
    ScaleNode(Stars,xs,ys,zs)
    
  EndIf
  If KeyboardPushed(#PB_Key_Q) ; up move
    up + 0.1
    MoveNode(Stars,0,up,depth,#PB_Absolute)
   ElseIf KeyboardPushed(#PB_Key_A) ; down move
    up - 0.1
    MoveNode(Stars,0,up,depth,#PB_Absolute)
    ElseIf KeyboardPushed(#PB_Key_W) ; forward move
    depth - 0.1
    MoveNode(Stars,0,up,depth,#PB_Absolute)
    ElseIf KeyboardPushed(#PB_Key_S) ; inward move
    depth + 0.1
    MoveNode(Stars,0,up,depth,#PB_Absolute)

  EndIf
   If KeyboardPushed(#PB_Key_Escape)
      Quit = #True
    EndIf
    
    
Until Quit = #True Or Event = #PB_Event_CloseWindow
FreeBasic OpenGL code: i don't know the original site for this code, its title is "Quaternion Fractal program" :

Code: Select all

'Quaternion Fractal program

#include "GL/gl.bi"
#include "GL/glu.bi"
#include "GL/glut.bi"
#include "crt.bi"

declare sub doMain( )
declare sub calcit( )
declare function calcleng( x as GLfloat, y as GLfloat, z as GLfloat) as GLfloat

randomize timer

dim shared as GLfloat dx, dy, x, y, z
dim shared as Long wd, ht, i, count, n, iter
dim shared as GLfloat mouseX, mouseY
dim shared as GLfloat aff(15)
dim shared as GLfloat w, leng, tx, ty, tz, tem
dim shared as GLfloat cr, ci, cj, ck, wk, incr, dist
dim shared as Long mand, zval
dim shared as GLuint quat

for i = 0 to 15
    if i mod 5 = 0 then
        aff(i) = 1.0
    else
        aff(i) = 0.0
    end if
next i
                        
wd = 600
ht = 600

'defines the shape of the Julia Set
cr = -0.200
ci = 0.800
cj = 0.000
ck = 0.000
wk = 0.000

'mand = 0 is Julia Set
'mand = 1 is Mandelbrot 3D
mand = 0

'zval = 1 shows entire set
'zval = 0 cuts set in half
'zval = 0 is an interesting effect
zval = 1

'for a more precise set increase
'iter.  However, too precise may
'not plot anything!  Recommend 25
iter = 25

'increments of 1 million points
'20 = 20 million random points
'tested for inclusion in the set
'try 100, but be patient!
incr = 25

doMain

sub doInitGL
    
	glClearColor 0.0, 0.0, 0.0, 0.0
	glEnable GL_DEPTH_TEST
    calcit()
end sub

sub doReshapeGL CDECL ( byval w as integer, _
                        byval h as integer )
    
    glMatrixMode GL_PROJECTION
    glLoadIdentity
    glViewport 0, 0, w, h
    
    gluPerspective  45.0, 1.0, 1.0, 1000.0 
    gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
    glMatrixMode GL_MODELVIEW
    glLoadIdentity
    
end sub

'creates the display list
sub calcit
    dim as GLfloat zz
    dim as GLint foo
    count = 0
    
    if zval = 0 then
        zz = 2.0
    else
        zz = 4.0
    end if
    
    quat = glGenLists(1)
    glNewList(quat, GL_COMPILE)
    glBegin(GL_POINTS)
    for foo = 0 to 1000000*incr
        x = 4.0*rnd-2.0
        y = 4.0*rnd-2.0
        z = zz*rnd-2.0
        
        'calls the quaternion calculation
        leng = calcleng(x,y,z)
        
        if leng < 4 then
            glColor3f(x+cos(15*leng),y+sin(1-leng)*cos(5*leng),z+sin(0.75*leng))
            glVertex3f(x,y,z)
        end if
    next foo
    glEnd()
    glEndList()
end sub

'quaternion calculations
function calcleng( x as GLfloat,  y as GLfloat,  z as GLfloat) as GLfloat
    dim as GLfloat w, kr, ki, kj, kk
    w = wk
    n = 0
    if mand = 1 then 'full Mandelbrot set
        kr = x
        ki = y
        kj = z
        kk = 0
    else                'Julia Set
        kr = cr
        ki = ci
        kj = cj
        kk = ck
    end if
    
    do
        tem = x+x
        x = x*x-y*y-z*z-w*w+kr
        y = tem*y + ki
        z = tem*z + kj
        w = tem*w + kk
        
        n+=1
        dist = x*x+y*y+z*z+w*w
        
        if dist > 4 then n = iter
    loop while n < iter
        
    return dist
end function

sub doRender cdecl
    
    glClear GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT
    glMatrixMode GL_MODELVIEW
    
    glPushMatrix
    glLoadIdentity
    glMultMatrixf @aff(0)
    
    'glPushMatrix
    glCallList(quat)
    
    'glPopMatrix
    
    glPopMatrix            
    glutSwapBuffers
    
end sub

sub mousemotion CDECL(byval x as integer, byval y as integer)
    mouseX = x
    mouseY = y
end sub

sub doInput CDECL ( byval kbcode as unsigned byte, _
              byval mousex as integer, _
              byval mousey as integer )
              
    if ( kbcode = 27 ) then
        'doShutdown
        end 0
    end if

end sub

sub chaptrack
    dx = (mouseX - wd/2)/256.0
    dy = (mouseY - ht/2)/256.0
    glMatrixMode GL_TEXTURE
    glPushMatrix
    glLoadIdentity
    glRotatef(dx, 0.0, 1.0, 0.0)
    glRotatef(dy, 1.0, 0.0, 0.0)
    glMultMatrixf @aff(0)
    glGetFloatv GL_TEXTURE_MATRIX, @aff(0)
    glPopMatrix
    
end sub

sub doIdle cdecl
    chaptrack
    glutPostRedisplay
end sub

sub doMain
    
    glutInit 1, strptr( " " )    
    
    glutInitWindowPosition 0, 0
    glutInitWindowSize wd, ht
    glutInitDisplayMode GLUT_RGBA or GLUT_DOUBLE or GLUT_DEPTH
    glutCreateWindow "FreeBASIC OpenGL example"
    
    doInitGL
    
    glutDisplayFunc  @doRender
    glutIdleFunc     @doIdle
    glutReshapeFunc  @doReshapeGL
    glutKeyboardFunc @doInput
    glutPassiveMotionFunc @mousemotion
    
    glutMainLoop

end sub



Last edited by applePi on Tue Jul 14, 2015 9:10 am, edited 1 time in total.
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: MandelBrot set 3D Demo

Post by davido »

Hi applePi,

Thank you for sharing.

I'm using 5.1 Windows 7/64

White.jpg resides in the same folder as the code.
Baulks on line 85: CreateMaterial(0, LoadTexture(0, "White.jpg"))

ERROR the specified texture is null.

Any idea what I'm doing wrong?
DE AA EB
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: MandelBrot set 3D Demo

Post by IdeasVacuum »

white.jpg should be in Data/Textures
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: MandelBrot set 3D Demo

Post by davido »

Hi IdeasVacuum,

No such folder, so I made one.

Same problem, I'm afraid.
DE AA EB
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: MandelBrot set 3D Demo

Post by IdeasVacuum »

That's really nice ApplePi - I had no idea about the use of 3D points!

This line: CreateMesh(1, #PB_Mesh_PointList, #False)
Should be: CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Dynamic)
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: MandelBrot set 3D Demo

Post by IdeasVacuum »

davido wrote:Hi IdeasVacuum,

No such folder, so I made one.

Same problem, I'm afraid.
You can do this instead, no image required:

Code: Select all

              CreateTexture(0,16,16)

               StartDrawing(TextureOutput(0))
                        Box(0, 0, 16, 16,RGB(255,255,255))
                StopDrawing()

CreateMaterial(0, TextureID(0))
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: MandelBrot set 3D Demo

Post by applePi »

Hi
in the official Meshmanual2.pb example there is
Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
....
CreateMaterial(0, LoadTexture(0, "White.jpg"))
the same exactly as my code
any way you can copy the white.jpg to the same folder as the code
and add
Add3DArchive("/", #PB_3DArchive_FileSystem)

i have tried it just now
use the latest version PB_5.10
PS: you can open ms paint program and save the blank white to white.jpg , i have tried it now.
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: MandelBrot set 3D Demo

Post by applePi »

Thanks IdeasVacuum for the tip, yes it works with:
CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Dynamic)
i think the possible usage of points 3D is to plot scientific data, such as i can imagine plotting DNA molecules in wich every sort of molecule have different color.
a million usage can be imagined. astronomy, earthquaks....
PS:
i want to think how to make a thicker points , this is by combining more points to symbolize one point. of course we can use circles, spheres. but the points lists seems very good.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: MandelBrot set 3D Demo

Post by IdeasVacuum »

i want to think how to make a thicker points
There might well be an existing way to do that, I don't know. I have been using spheres - you only need one sphere mesh and then instance it as an Entity many times.

Re the texture bitmap - when it's only a plain colour, there is little point in loading an image when you can simply create one on-the-fly.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
davido
Addict
Addict
Posts: 1890
Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK

Re: MandelBrot set 3D Demo

Post by davido »

Hi IdeasVacuum and applePi,

It's really kind of you both for taking the time to walk me through this problem.

Works! Now. :D
DE AA EB
User avatar
Comtois
Addict
Addict
Posts: 1431
Joined: Tue Aug 19, 2003 11:36 am
Location: Doubs - France

Re: MandelBrot set 3D Demo

Post by Comtois »

i want to think how to make a thicker points
you can change the size point in a material script

http://www.ogre3d.org/docs/manual/manua ... t_005fsize
Please correct my english
http://purebasic.developpez.com/
applePi
Addict
Addict
Posts: 1404
Joined: Sun Jun 25, 2006 7:28 pm

Re: MandelBrot set 3D Demo

Post by applePi »

thats wonderfull Comtois thank you
i have used the script material with points size 4 http://www.ogre3d.org/forums/viewtopic.php?f=2&t=60090
then saving the Points04.material in the Data/Scripts folder
Points04.material :

Code: Select all

material def_Points_04
{
   receive_shadows off
   technique
   {
      pass
      {
         //point_sprites on
         //polygon_mode points
         point_size 4
         lighting off
         diffuse vertexcolour
      }
   }
}
then using this code:
CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Dynamic )
GetScriptMaterial(0, "def_Points_04")
SetMeshMaterial(1, MaterialID(0))
DisableMaterialLighting(0, #True)


i draw mandelbrot 3d for just 10000 iterations, and it show a big points, really great colorful points.
@IdeasVacuum, i agree with creating texture bitmap on the fly, more handy to use than pictures.

to try the new version for 10000 iterations only with points size 4:

Code: Select all

Enumeration
   #MESH
   #LIGHT
   #CAMERA_ONE
   #BUTTON
   #mainwin
 EndEnumeration
 ;constants for the biomorph function
 #constreal = 0.5 
  #constimag = 0 
  #screenheight = 500
  #screenwidth = 500
  
Global.f dx, dy, x, y, z
Global wd, ht, i, count, n, iter
Global.f w, leng, tx, ty, tz, tem
Global.f cr, ci, cj, ck, wk, inc, distance
Global mand, zval
Global.f angle
Define.f red, green, blue
;zval = 1 shows entire set
;zval = 0 cuts set in half
;zval = 0 is an interesting effect
wd = 500
ht = 500
;defines the shape of the Julia Set
cr = -0.200
ci = 0.800
cj = 0.000
ck = 0.000
wk = 0.000
;mand = 0 is Julia Set
;mand = 1 is Mandelbrot 3D
mand = 1
;zval = 1 shows entire set
;zval = 0 cuts set in half
;zval = 0 is an interesting effect
zval = 1
iter = 5
inc = 5 
;#quat = 1
zval = 1
iter = 5
inc = 5 
Procedure.f RandF(Min.f, Max.f, Resolution.i = 10000)
  ProcedureReturn (Min + (Max - Min) * Random(Resolution) / Resolution)
EndProcedure

Quit.b = #False
rot.l=1 :stopFlag = 1
xs.f = 0.3:ys.f = 0.3:zs.f = 0.3
x.f: y.f :z.f: x0.f: y0.f=1 :z0.f
rotx.f:roty.f=1:rotz.f :rotx0.f: roty0.f: rotz0.f
up.f = 2.2: depth.f=0

ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "PgUp PgD scale mesh..Arrows for rotation, space: stop/rotate,  QA Up/Down, WS far/near", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  ButtonGadget(#BUTTON, 0, DesktopHeight(0)-60, 60, 30, "rotate/stop") 

;Initialize environment
InitEngine3D()
InitSprite()
OpenWindowedScreen(WindowID(#mainwin), 0, 0, DesktopWidth(0), DesktopHeight(0)-70, 0, 0, 0)
WorldShadows(#PB_Shadow_Additive)

InitKeyboard()
SetFrameRate(60)

Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive("Data/Scripts", #PB_3DArchive_FileSystem)
Parse3DScripts()

CreateLight(0,RGB(255,255,255),-100,40,30)
AmbientColor(RGB(100,100,100))

CreateCamera(#CAMERA_ONE, 0, 0, 400, 400)
MoveCamera(#CAMERA_ONE, 0, 4, 9)
CameraLookAt(#CAMERA_ONE, 0, 2, 0)

RotateCamera(#CAMERA_ONE, -15, 0, 0)
EndIf

SetActiveGadget(#BUTTON)
;SkyDome("clouds.jpg", 100) ;for blue color background

;- Mesh Stars

;PointsSize = GetScriptMaterial(#PB_Any, "def_Points_04")
CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Dynamic )
;CreateMesh(1, #PB_Mesh_PointList, #False)

GetScriptMaterial(0, "def_Points_04")
SetMeshMaterial(1, MaterialID(0))
DisableMaterialLighting(0, #True)

Global Stars = CreateNode(#PB_Any)
AttachNodeObject(Stars, MeshID(1))


Procedure.f calcleng( x.f,  y.f,  z.f)
    w.f: kr.f: ki.f: kj.f: kk.f
    w = wk
    n = 0
    If mand = 1  ;full Mandelbrot set
        kr = x
        ki = y
        kj = z
        kk = 0
    Else                ;else draw Julia Set
        kr = cr
        ki = ci
        kj = cj
        kk = ck
    EndIf
    
    While n < iter
        tem = x+x
        x = x*x-y*y-z*z-w*w+kr
        y = tem*y + ki
        z = tem*z + kj
        w = tem*w + kk
        
        n+1
        distance = x*x+y*y+z*z+w*w
        
        If distance > 4 
          n = iter
        EndIf
        
    Wend
        
    ;Return distance
    ProcedureReturn distance
  
EndProcedure

  

Procedure calcit()
    zz.f
    foo.l
    iterations = 10000
    count = 0
    
    If zval = 0
        zz = 2.0
    Else
        zz = 4.0
    EndIf
      
      For foo = 0 To iterations
          ;x.f = RandF(0, 1)
          ;y.f = RandF(0, 1)
          x.f = RandF(-2, 2)
          y.f = RandF(-2, 2)
          
          z.f = zz*RandF(0, 1) -2.0
          
          ;calls the quaternion calculation
          leng.f = calcleng(x,y,z)
          
          If leng < 4 
              MeshVertexPosition(x, y, z)
              red = (x+Cos(15*leng))*255
              green = (y+Sin(1-leng)*Cos(5*leng))*255
              blue = (z+Sin(0.75*leng))*255
              If red < 0 : red = 0 : EndIf
              If green < 0 : green = 0 : EndIf
              If blue < 0 : blue = 0 : EndIf
              ;If red > 255 : red = red-255 : EndIf
              ;If green > 255 : green = green-255 : EndIf
              ;If blue > 255 : blue = blue-255 : EndIf
              
              ;MeshVertexColor(RGBA(red,green,blue,0))
              MeshVertexColor(RGB(red,green,blue))
                           
          EndIf
          
        Next 
        FinishMesh(#False)
        NormalizeMesh(1)
      
EndProcedure


calcit()  ; calling the mandel 3D or julia generator function

;Main loop
Repeat
  Event = WindowEvent()
  If Event = #PB_Event_Gadget
    Select EventGadget()
      Case #BUTTON
        If rot = 0
          rot = 1
          rotx= rotx0:roty=roty0:rotz=rotz0 ; restore rotation status
          stopFlag = 1
          
        Else
          rot = 0
          rotx0= rotx:roty0=roty:rotz0=rotz ;back up rotation status
          rotx=0:roty=0:rotz=0
          stopFlag = 0
          
        EndIf
                    
    EndSelect
  EndIf 
  If stopFlag=1
    x + rotx
    y + roty
    z + rotz
  EndIf
  
   RotateNode(Stars, x, y, z)
   
   RenderWorld()
   FlipBuffers()

  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Up)  ; rotate left
    rotx=1:roty=0:rotz=0
    rotx0 = rotx: roty0 = roty :rotz0 = rotz
    x + rotx
    y + roty
    z + rotz
    stopFlag=0
    rot = 0
  ElseIf KeyboardPushed(#PB_Key_Down) ; rotate right
    rotx=-1:roty=0:rotz=0
    rotx0 = rotx: roty0 = roty :rotz0 = rotz
    x + rotx
    y + roty
    z + rotz
    stopFlag=0
    rot = 0
  ElseIf KeyboardPushed(#PB_Key_Right)   ; rotate up
    rotx=0:roty=1:rotz=0
    rotx0 = rotx: roty0 = roty :rotz0 = rotz
    x + rotx
    y + roty
    z + rotz
    stopFlag=0
    rot = 0
  ElseIf KeyboardPushed(#PB_Key_Left) ; rotate down
    rotx=0:roty=-1:rotz=0 
    rotx0 = rotx: roty0 = roty :rotz0 = rotz
    x + rotx
    y + roty
    z + rotz
    stopFlag=0
    rot = 0
  EndIf 
  
  If KeyboardPushed(#PB_Key_PageUp) ; scale up model
    xs.f = 1.1:ys.f = 1.1:zs.f = 1.1
    ScaleNode(Stars,xs,ys,zs)
    
  ElseIf KeyboardPushed(#PB_Key_PageDown) ; scale down model
    xs = 0.9:ys = 0.9:zs= 0.9
    ScaleNode(Stars,xs,ys,zs)
    
  EndIf
  If KeyboardPushed(#PB_Key_Q) ; up move
    up + 0.1
    MoveNode(Stars,0,up,depth,#PB_Absolute)
   ElseIf KeyboardPushed(#PB_Key_A) ; down move
    up - 0.1
    MoveNode(Stars,0,up,depth,#PB_Absolute)
    ElseIf KeyboardPushed(#PB_Key_W) ; forward move
    depth - 0.1
    MoveNode(Stars,0,up,depth,#PB_Absolute)
    ElseIf KeyboardPushed(#PB_Key_S) ; inward move
    depth + 0.1
    MoveNode(Stars,0,up,depth,#PB_Absolute)

  EndIf
   If KeyboardPushed(#PB_Key_Escape)
      Quit = #True
    EndIf
    
    
Until Quit = #True Or Event = #PB_Event_CloseWindow
Post Reply