Page 1 of 3

Klein Bottle example

Posted: Tue Mar 12, 2013 8:40 am
by applePi
2 examples for klein bottle ; the first is using textured triangles. using this parametric equations in this article http://paulbourke.net/geometry/klein/
it has two orbits the inner circles (orbits) which in turn going in another orbit which forms the klein bottle
Image Image
to see it in wireframe uncomment line 47

Code: Select all

Enumeration
   #MESH
   #LIGHT
   #CAMERA_ONE
   #BUTTON
   #mainwin
 EndEnumeration

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=0.5:rotz.f :rotx0.f: roty0.f: rotz0.f
up.f = 1.8: depth.f=0

ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "PgUp PgD scale mesh..Arrows for rotation, space: stop/rotate,  QA far/near, key_pad R/L/U/D", #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)-60, 0, 0, 0)
;WorldShadows(#PB_Shadow_Additive)

InitKeyboard()
SetFrameRate(60)

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

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
; material for the plot
CreateMaterial(0, LoadTexture(0, "terrain_texture.jpg"))
;MaterialShadingMode(0, #PB_Material_Wireframe)
MaterialCullingMode(0, #PB_Material_NoCulling)
DisableMaterialLighting(0, #True)
CreateMesh(1, #PB_Mesh_TriangleList , #PB_Mesh_Static )
SetMeshMaterial(1, MaterialID(0))
      u.f: v.f: r.f
      majorOrbit.l = 30 : minorOrbit.l = 30
      majorStep.f   = 2 * #PI / majorOrbit
      minorStep.f   = 2 * #PI / minorOrbit
      i.l: j.l :txu.f : txv.f
 
      For i = 0 To majorOrbit
        u = i * majorStep
        For j = 0 To minorOrbit
          v = j * minorStep
          r = 4 * (1 - (Cos(u)/2))
        If u <= #PI
          x = 6 * Cos(u) * (1 + Sin(u)) + r * Cos(u) * Cos (v)
          y = 16 * Sin(u) + r * Sin(u) * Cos(v)
        ElseIf u > #PI And u <=2*#PI   
          x = 6 * Cos(u) * (1 + Sin(u)) + r * Cos(v+#PI)
          y = 16 * Sin(u)
        EndIf
        z = r * Sin(v)
          
          MeshVertexPosition(x, y, z);
          MeshVertexTextureCoordinate(txu, txv)
          MeshVertexNormal(x, y, z)
          ; texture the whole bottle with one picture stretched
          txv = txv + 1/minorOrbit ; texture coordinates
          
        Next
        txv = 0
        txu = txu + 1/majorOrbit   ; texture coordinates
        
      Next
    ; making Faces
    For i = 0 To majorOrbit-1
      For j = 0 To minorOrbit
          MeshFace(t,t+1,t + minorOrbit+1)
          MeshFace(t + minorOrbit+1,t + minorOrbit+2,t+1 )
          If i=majorOrbit-1 And j=minorOrbit-1 ;bypass the last triangle
            minorOrbit-1
          EndIf 
          t + 1   
          
     Next
     
   Next  
    NormalizeMesh(1)
    FinishMesh(#True)
    CreateEntity(1, MeshID(1), MaterialID(0))  
    ScaleEntity(1,0.2, 0.2, 0.2)
  ;Main loop
  MoveEntity(1,0,up,depth,#PB_Absolute) 
  x = 180: y=0: z=0 : h.f
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
  
   RotateEntity(1, 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
    ScaleEntity(1,xs,ys,zs)
    
  ElseIf KeyboardPushed(#PB_Key_PageDown) ; scale down model
    xs = 0.9:ys = 0.9:zs= 0.9
    ScaleEntity(1,xs,ys,zs)
    
  EndIf
  If KeyboardPushed(#PB_Key_Pad8) ; up move
    up + 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)
   ElseIf KeyboardPushed(#PB_Key_Pad2) ; down move
    up - 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)
  ElseIf KeyboardPushed(#PB_Key_Pad6)
    h + 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)
    ElseIf KeyboardPushed(#PB_Key_Pad4)
    h - 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)
    
    ElseIf KeyboardPushed(#PB_Key_Q) ; forward move
    depth - 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)
    ElseIf KeyboardPushed(#PB_Key_A) ; inward move
    depth + 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)

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


the second klein bottle are easier to implement, using point plotting for the same equations
Image

Code: Select all

Enumeration
   #MESH
   #LIGHT
   #CAMERA_ONE
   #BUTTON
   #mainwin
 EndEnumeration

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=0.5:rotz.f :rotx0.f: roty0.f: rotz0.f
up.f = 1.8: depth.f=0

ExamineDesktops()
If OpenWindow(#mainwin, 0, 0, DesktopWidth(0), DesktopHeight(0), "PgUp PgD scale mesh..Arrows for rotation, space: stop/rotate,  QA far/near, key_pad R/L/U/D", #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_3DArchive_FileSystem)
Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)

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 
CreateTexture(0,32,32)
  StartDrawing(TextureOutput(0))
    Box(0,0,32,32,RGB(255,255,255))
  StopDrawing()
CreateMaterial(0,TextureID(0))
DisableMaterialLighting(0, #True)
CreateMesh(1, #PB_Mesh_PointList, #PB_Mesh_Static)
DisableMaterialLighting(0, #True)
SetMeshMaterial(1, MaterialID(0))

      x.f: y.f :z.f : u.f: v.f: r.f
      majorOrbit.l = 100 : minorOrbit.l = 100
      majorStep.f   = 2 * #PI / majorOrbit
      minorStep.f   = 2 * #PI / minorOrbit
      i.l: j.l
 
      For i = 0 To majorOrbit
        u = i * majorStep
        For j = 0 To minorOrbit
          v = j * minorStep
          r = 4 * (1 - (Cos(u)/2))
        If u <= #PI
          x = 6 * Cos(u) * (1 + Sin(u)) + r * Cos(u) * Cos (v)
          y = 16 * Sin(u) + r * Sin(u) * Cos(v)
        ElseIf u > #PI And u <=2*#PI   
          x = 6 * Cos(u) * (1 + Sin(u)) + r * Cos(v+#PI)
          y = 16 * Sin(u)
        EndIf
        z = r * Sin(v)
          
          MeshVertexPosition(x, y, z);
          MeshVertexColor(RGB(0,255,0))
          
        Next
      Next
      
    NormalizeMesh(1)
    FinishMesh(#True)
    CreateEntity(1, MeshID(1), MaterialID(0))  
    ScaleEntity(1,0.2, 0.2, 0.2)
  ;Main loop
  MoveEntity(1,0,up,depth,#PB_Absolute) 
  x = 180: y=0: z=0 : h.f
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
  
   RotateEntity(1, 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
    ScaleEntity(1,xs,ys,zs)
    
  ElseIf KeyboardPushed(#PB_Key_PageDown) ; scale down model
    xs = 0.9:ys = 0.9:zs= 0.9
    ScaleEntity(1,xs,ys,zs)
    
  EndIf
  If KeyboardPushed(#PB_Key_Pad8) ; up move
    up + 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)
   ElseIf KeyboardPushed(#PB_Key_Pad2) ; down move
    up - 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)
  ElseIf KeyboardPushed(#PB_Key_Pad6)
    h + 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)
    ElseIf KeyboardPushed(#PB_Key_Pad4)
    h - 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)
    
    ElseIf KeyboardPushed(#PB_Key_Q) ; forward move
    depth - 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)
    ElseIf KeyboardPushed(#PB_Key_A) ; inward move
    depth + 0.1
    MoveEntity(1,h,up,depth,#PB_Absolute)

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



Re: Klein Bottle example

Posted: Tue Mar 12, 2013 11:14 am
by davido
Hi applePi,

Thanks for sharing. Nice demo.

I shall enjoy learning how its done. :D

Re: Klein Bottle example

Posted: Thu Mar 14, 2013 1:52 am
by electrochrisso
Runs nice and smooth, even on my underpowered net-book, great code, thanks for sharing. :)

Re: Klein Bottle example

Posted: Thu Mar 14, 2013 9:19 am
by MachineCode
Can't run it because I get this error:

Code: Select all

The program can't start because d3dx9_42.dll is missing from your computer. Try reinstalling the program to fix this problem.
No, I don't want to install that DLL to "make it work". Shouldn't it be part of PureBasic or something? Or shouldn't PureBasic return an error if it can't load it?

Re: Klein Bottle example

Posted: Thu Mar 14, 2013 10:13 am
by Fred
MachineCode wrote:Can't run it because I get this error:

Code: Select all

The program can't start because d3dx9_42.dll is missing from your computer. Try reinstalling the program to fix this problem.
No, I don't want to install that DLL to "make it work". Shouldn't it be part of PureBasic or something? Or shouldn't PureBasic return an error if it can't load it?
Did you tried with 5.11 ? It shouldn't display this. But if you want the example work, you need to install directx, we can't ship it with PureBasic it's too big.

Re: Klein Bottle example

Posted: Thu Mar 14, 2013 10:24 am
by infratec
Hi applePi,

the first code runs fine,
the second generates an IMA at RenderWorld()

PB 5.10 x86 on Win7 x64

Bernd

Re: Klein Bottle example

Posted: Thu Mar 14, 2013 10:38 am
by infratec
Found something:

If I comment

Code: Select all

;WorldShadows(#PB_Shadow_Additive)
like in the first code, it works :!:

Bernd

P.S.: in line 24 direct after OpenWindowedScreen()

Re: Klein Bottle example

Posted: Thu Mar 14, 2013 1:16 pm
by applePi
thank you Bernd for the note, i have edited that line
but it does not produce error with me with or without shadow, windows xp, PB 5.11bX

Re: Klein Bottle example

Posted: Fri Mar 15, 2013 1:21 am
by electrochrisso
infratec wrote:Hi applePi,

the first code runs fine,
the second generates an IMA at RenderWorld()

PB 5.10 x86 on Win7 x64

Bernd
I get this error with RenderWorld() for many examples on my netbook, I can sometimes get it to work if I use opengl subsystem, it worked this time for this code.

Now I go back to directX and it works if I comment out WorldShadows(#PB_Shadow_Additive), like you did bernd.

It would be good to have documentation in the PB help, or somewhere on how to set up the 3D to work consistently with most, if not all, graphics chips. :)

Re: Klein Bottle example

Posted: Fri Mar 15, 2013 3:05 am
by IdeasVacuum
MachineCode wrote:Can't run it because I get this error:

Code: Select all

The program can't start because d3dx9_42.dll is missing from your computer. Try reinstalling the program to fix this problem.
No, I don't want to install that DLL to "make it work". Shouldn't it be part of PureBasic or something? Or shouldn't PureBasic return an error if it can't load it?
Compiler Options: Try the Library Subsystem OpenGL instead -d3dx9_42.dll will not be required.

Re: Klein Bottle example

Posted: Fri Mar 15, 2013 11:27 am
by Fred
You will still need it, as DX9 lib is linked statically to engine3d.dll. It will probably change for 5.20.

Re: Klein Bottle example

Posted: Fri Mar 15, 2013 7:23 pm
by moogle
Fred wrote:Did you tried with 5.11 ? It shouldn't display this. But if you want the example work, you need to install directx, we can't ship it with PureBasic it's too big.
You could include the DX Runtime Web Installer Fred, it's much smaller.

Re: Klein Bottle example

Posted: Sat Mar 16, 2013 12:11 pm
by Fred
From what I understand from the MS licenses, you can't package the web installer, you need to package the 'Redistributable' package, which is 95 MB.

Re: Klein Bottle example

Posted: Sat Mar 16, 2013 3:34 pm
by Ramihyn_
Fred wrote:From what I understand from the MS licenses, you can't package the web installer, you need to package the 'Redistributable' package, which is 95 MB.
But you could provide a button or a link to an URL like this :

English : http://www.microsoft.com/en-us/download ... aspx?id=35
German : http://www.microsoft.com/de-de/download ... aspx?id=35

If no compatible DirectX version is detected, you could warn the user that it is required (for some functionality) and should be installed. If a compatible DirectX version is detected, you could remind the user that keeping their DX version up to date, ensures the maximum compatibility with Purebasic. For the first case (no compatible DX found), you could mildly push the user to open the URL (or just open it unless the user clicks "skip" instead of "continue" or any other button to close the installer. In the second case of having found a compatible version (but not knowing if it is the most recent one), clicking the button to update the DX version, would be optional but suggested.

The link is referenced by MS FAQ articles and other MS resources, so it will probably not change easily.

I know that i would appreciate this during install :)

Re: Klein Bottle example

Posted: Sat Mar 16, 2013 11:34 pm
by LuCiFeR[SD]
and an installer check for the NV CG toolkit too wouldn't go amiss.