Page 2 of 2

Re: Circular Tube ( UFO ) & Conical and Pyramidal tubes

Posted: Mon Dec 29, 2014 1:34 pm
by applePi
@StarBootics, as electrochrisso said you need advice from someone who have ubunto, since i use windows system.
but can you run the examples in the 3D\Demos examples such as MeshManualFlag.pb or MeshManualParametrics.pb ?
if not then you need to install driveres for your graphics card.
davido above said that it Works on Mac.
i have changed the position of Parse3DScripts() after the OpenWindowedScreen , in case .

Re: Circular Tube ( UFO ) & Conical and Pyramidal tubes

Posted: Thu Jan 01, 2015 7:10 am
by StarBootics
Hello again,

I'm very sorry but examples from the 3D demo work very well. It's really your example the problem.
I think the best solution is to start with a working example and copy paste your code into the working code...

Thanks anyway
StarBootics

Re: Circular Tube ( UFO ) & Conical and Pyramidal tubes

Posted: Thu Jan 01, 2015 11:36 am
by applePi
StarBootics, i have used MeshManualFlag.pb from a PB 5.31 Linux distribution, and i filled the example with my example deleting the windows screen management and replacing it with
Screen3DRequester.pb and Screen3DEvents() like the PB official example .
the example should be saved to examples\3d\demos like the MeshManualFlag.pb
it works okay on windows system.
* it is possible Linux differentiate between the "Examples/3D/Data/Textures" and the "examples/3d/Data/Textures" something about capital and small letters, since in linux distr it is "examples" while in windows distr it is "Examples". this is may be the cause StarBootics gets the error msg "The specified 'Texture' is null". " on all *.jpg texture.
** there is still the OpenWindowedScreen and OpenWindow problem ,we can find these functions in the Linux distribution in the FacialAnimation.pb and CarPhysic.pb , so i suggest to replace the values which are suitable for your screen like that in the FacialAnimation.pb or CarPhysic.pb

save this to: examples\3d\Demos , in fact it works from any place , because of:
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
Space toggle rotation, W toggle wire/solid Frame. arrows+mouse to move/rotate camera
Edit: i have changed the wood.jpg to Wood.jpg

Code: Select all

Enumeration
  #Window = 500
  #ground
  #Camera
  #Light1
  #sphere
  #plane
  #RedMaterial
  #tube      
EndEnumeration

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

#CameraSpeed = 2

Global bands = 8 ;number of points of every ring (circle)
#Rings = 2 ;number of Rings over all the smallest tube (always 2, start ring and end ring)
Global divisions = 100
Structure vector3d
  x.f
  y.f
  z.f
EndStructure

Structure vertex
  x.f
  y.f
  z.f
EndStructure


Declare DrawTube (x.f, y.f,z.f, x2.f, y2.f, z2.f, Radius.f, bands)
Declare tubesCircle()

Define.f KeyX, KeyY, MouseX, MouseY

; beginning of the frenet sqaure approximation 5 procedures  
Procedure vector_cross(*v1.vector3d, *v2.vector3d, *vout.vector3d)
    *vout\x = (*v1\y * *v2\z) - (*v2\y * *v1\z)
    *vout\y = (*v1\z * *v2\x) - (*v2\z * *v1\x)
    *vout\z = (*v1\x * *v2\y) - (*v2\x * *v1\y)
EndProcedure

Procedure.f vector_magnitude(*v.vector3d)
    mag.f
    mag = Sqr(*v\x * *v\x + *v\y * *v\y + *v\z * *v\z)
    If mag = 0:mag = 1:EndIf
    ProcedureReturn mag
EndProcedure

Procedure vector_normalize (*v.vector3d)
    mag.f
    mag = vector_magnitude(*v)
    *v\x = *v\x / mag
    *v\y = *v\y / mag
    *v\z = *v\z / mag
EndProcedure


Procedure vector_add (*v1.vector3d, *v2.vector3d, *vout.vector3d)
    *vout\x = *v1\x + *v2\x
    *vout\y = *v1\y + *v2\y
    *vout\z = *v1\z + *v2\z
EndProcedure

Procedure vector_sub (*v1.vector3d, *v2.vector3d, *vout.vector3d)
    *vout\x = *v1\x - *v2\x
    *vout\y = *v1\y - *v2\y
    *vout\z = *v1\z - *v2\z
EndProcedure

If InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Packs/skybox.zip", #PB_3DArchive_Zip)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, 200, 300, 150, #PB_Absolute)
    CameraLookAt(#Camera,0,0,0)
    CameraBackColor(#Camera, RGB(200,255,200))
        
    CreateMaterial(2, LoadTexture(2, "ground_diffuse.png"))
    MaterialCullingMode(2, #PB_Material_NoCulling)
    DisableMaterialLighting(2, #True)
    ScrollMaterial(2, 0, 0, #PB_Material_Animated) 
    SetMaterialColor(2, #PB_Material_AmbientColor, RGB(250, 255, 0))
    SetMaterialColor(2, #PB_Material_SpecularColor, RGB(255, 255, 0))
    
    CreateMaterial(0, LoadTexture(0, "Wood.jpg"))
    DisableMaterialLighting(0, #True)
    
    GetScriptMaterial(#RedMaterial, "Color/Red")
    
    CreateLight(#Light1, RGB(255, 255, 255), 0, 100, 50)
    AmbientColor(RGB(255, 255, 255))
    
    EnableWorldPhysics(#True)
WorldGravity(-100)
CreateCube(#plane,1)
CreateEntity(#plane,MeshID(#plane),MaterialID(0), 0, -21, 0)
ScaleEntity(#plane, 300,1, 300)
EntityPhysicBody(#plane, #PB_Entity_StaticBody)

wireFrame = 1

tubesCircle()
CreateSphere(#sphere, 7)
CreateEntity(#sphere, MeshID(#sphere), MaterialID(#RedMaterial), 95, 10,0)
EntityPhysicBody(#sphere, #PB_Entity_SphereBody, 1,5,1)
EntityPhysicBody(#tube, #PB_Entity_StaticBody)

Tex1  = LoadTexture(#PB_Any, "MRAMOR6X6.jpg")
AddMaterialLayer(2, TextureID(Tex1), #PB_Material_Modulate)
rot = 1 : rotation.f = 0.4

    Repeat
      Screen3DEvents()
      
      If ExamineKeyboard()
         If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_E)
          x.f+0.001
          ScrollMaterial(2, x, 0, #PB_Material_Fixed  , 1)    
         EndIf 
        
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
            MaterialShadingMode(2, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
            MaterialShadingMode(2, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
        
      EndIf
      
      If ExamineMouse()
        MouseX = -(MouseDeltaX()/20)
        MouseY = -(MouseDeltaY()/20)
      EndIf
      
     
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
            
      ttt+1
      If ttt=100 ; give the sphere a pulse every 100 loops
        ApplyEntityImpulse(#sphere, 0, 200, 0,  0,1,-1)
        ttt=0
      EndIf
      If KeyboardReleased(#PB_Key_Space)
        If rot
          rotation.f = 0
          rot = 0
        Else
          rotation.f = 0.4
          rot = 1
          EndIf
        
      EndIf
          
      MoveCamera  (#Camera, KeyX, 0, KeyY)
      RotateCamera(#Camera,  MouseY, MouseX, 0, #PB_Relative)  
      RotateEntity(#tube, 0,rotation,0, #PB_Relative)
      
      x.f+0.003
      ScrollMaterial(2, x, 0, #PB_Material_Fixed  , 1)
      
      ttt+1
      If ttt=100 ; give the sphere a pulse every 100 loops
        ApplyEntityImpulse(#sphere, 0, 200, 0,  0,1,-1)
        ttt=0
      EndIf
      If KeyboardReleased(#PB_Key_Space)
            rot ! 1
      EndIf
          
                  
      RenderWorld()
      
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End

Procedure  DrawTube (x.f, y.f,z.f, x2.f, y2.f,z2.f, Radius.f, bands)
  x.f+0.00001 : y.f+0.00001 : z.f+0.00001 ; in rare cases when x,y,z where all zero:
  x2.f+0.00001 : y2.f+0.00001 : z2.f+0.00001; then without adding 0.00001 will gives erroneous shape 
  
  Dim vertx.vertex(2)
  lineVec.vector3d

   u.f: r.f
      
  txu.f : txv.f
   
  x1.f = x
  y1.f = y
  z1.f = z
  
  
  ;vector of the line between start vertex and the end vertex
  lineVec\x = x2 - x1
  lineVec\y = y2 - y1
  lineVec\z = z2 - z1
  
  
  tt.f = 0
  
  For i=0 To #Rings
        
      x = x1 + lineVec\x * tt 
      y = y1 + lineVec\y * tt 
      z = z1 + lineVec\z * tt
      tt + 1
      
       vertx(i)\x = x
       vertx(i)\y = y
       vertx(i)\z = z
       
   Next 
        
     current_point.vector3d
        next_point.vector3d
        T.vector3d
        B.vector3d
        N.vector3d
        p.f
     For i = 0 To #Rings-1
     
        ;center point
                
        current_point\x = vertx(i)\x
        current_point\y = vertx(i)\y
        current_point\z = vertx(i)\z
        ;next point For Frenet square
        
        next_point\x = vertx(i+1)\x
        next_point\y = vertx(i+1)\y
        next_point\z = vertx(i+1)\z

        ;T  = P' - P
        vector_sub(next_point, current_point, T)

        ;N = P' + P
        vector_add(next_point, current_point, N)

        ;B = T x N
        vector_cross(T, N, B)

        ;N = B x T
        vector_cross(B, T, N)

        ;Normalize vectors Or Else it won't work
        vector_normalize(B)
        vector_normalize(N)
        
        For j = 0 To bands
              new_point_x.f
              new_point_y.f
              
              ;rotate around the current point using normal rotation makes bands
            new_point_x = Sin(j * (#PI*2) / bands) * RADIUS
            new_point_y = Cos(j * (#PI*2) / bands) * RADIUS
            
                ;this is the coordinates of our point along the curve
            x = N\x * new_point_x + B\x * new_point_y + current_point\x
            y = N\y * new_point_x + B\y * new_point_y + current_point\y
            z = N\z * new_point_x + B\z * new_point_y + current_point\z
            
            MeshVertexPosition(x, y, z)
            MeshVertexTextureCoordinate(txu, txv)
            MeshVertexNormal(x, y, z)
            txv = txv + 1/#Rings
                         
         Next 
         txv = 0
         txu = txu + 1/bands
         
      Next 

      
         

  EndProcedure

  
  Procedure tubesCircle()
  CreateMesh(#tube , #PB_Mesh_TriangleList, #PB_Mesh_Static )  
  For i=1 To divisions
    ;divide the circle Circumference to arbitrary divisions      
    ;coordinates of a single point on the circle Circumference
      X.f=X+#PI*2/divisions 
      Z.f=Z+#PI*2/divisions
      XX.f=Cos(X)*100 ; 100 here is the radius of the big circle (big tube)
      ZZ.f=Sin(Z)*100
            
      X.f=X+#PI*2/divisions
      Z.f=Z+#PI*2/divisions
      XX2.f=Cos(X)*100
      ZZ2.f=Sin(Z)*100
      yy.f=0: yy2.f=0
            
      Radius = 20; radius of the tube cross section (lets say thickness/2)
      Bands = 8
            
      ; we gives the two adjacent points on the circle Circumference to the procedure
      ; which draws around every point a small circle made from arbitray divisions called bands, here it is 8
      DrawTube (xx, yy, zz, xx2, yy2, zz2, Radius, Bands)
            
    Next
   
      v.l=0
      For i = 0 To divisions+12 ;divisions is the number of circles the whole tube are made from
      For j = 0 To bands - 1 ; bands is the number of divisions every small circle (tube thickness) are made
          MeshFace(v,v+1,v + bands+1)
          MeshFace(v + bands+1,v + bands+2,v+1 )
          
          v + 1   
      Next
      Next  
   
    
    FinishMesh(#True)
    
    CreateEntity(#tube,MeshID(#tube),MaterialID(2) )
    NormalizeMesh(#tube)
    BuildMeshTangents(#tube)
    
  EndProcedure
  
 
 

Re: Circular Tube ( UFO ) & Conical and Pyramidal tubes

Posted: Fri Jan 02, 2015 6:36 pm
by StarBootics
Hello applePi,

The last code work fine.

Best regards
StarBootics

Re: Circular Tube ( UFO ) & Conical and Pyramidal tubes

Posted: Wed Jan 07, 2015 11:28 am
by falsam
Hello ApplePi :)

I tested this code.
:arrow: http://www.purebasic.fr/english/viewtop ... 09#p457509

When I add WorldShadows(#PB_Shadow_Additive), only the ballss appear

Code: Select all

    CameraBackColor(#Camera, RGB(200,200,200))    
    WorldShadows(#PB_Shadow_Additive)

Re: Circular Tube ( UFO ) & Conical and Pyramidal tubes

Posted: Wed Jan 07, 2015 1:52 pm
by applePi
Hi falsam
i will do research about this, the structure in the example are made from 10 smaller tubes.
but regarding the first example at the top, if we add before the Repeat the lines:
WorldShadows(#PB_Shadow_Modulative)
EntityRenderMode(#tube, #False)

also replace the light so it is inside the donut
CreateLight(#Light1, RGB(255, 255, 255), 90, 20, 10)

then we will see the shadow of the sphere on the donut walls.
someone have posted a question before about why we can't see shadow inside the houses or models, and the EntityRenderMode(#ground, #False) was the answer. can't find the thread.

also i remember that the way the triangles connected (clockwise or anticlockwise is very important for the shadow and light and the general appearance of the mesh.

i post in a hurry since my web connection are on and off from the extreme Weather, i will look more about the subject.
regards

Re: Circular Tube ( UFO ) & Conical and Pyramidal tubes

Posted: Fri Jan 09, 2015 5:53 pm
by applePi
Hi falsam
this is a not complete answer, many issues remains.
it seems we should add
NormalizeMesh(tube)
BuildMeshTangents(tube)

before FinishMesh(tube) and not after and the tubes will not disappears with shadow additive.

i think the vertices are connected clockwise on one of the triangles and it should be counter clockwise.
so we replace
MeshFace(v,v+1,v + bands+1)
MeshFace(v + bands+1,v + bands+2,v+1 )

with
MeshFace(v,v + bands+1, v+1)
MeshFace(v + bands+1, v + bands+2, v+1 )

i have done experiment on a simple construction labeling its vertices , i post it at the end just if needed

also we apply Samuel advice regarding MeshVertexNormal(0, 1, 0) after MeshVertexPosition(x, y, z)

the dilemma is that we need to give every tube the feature: EntityRenderMode(tube, 0)
so we can't show the shadow of the tubes itself on the ground
note that line 16-18: divisions = 10 ie the number of the tubes make the whole donut,
and bands = 8 ie the shape of every tube, and here it is octagonal. try bands = 20 and divisions =20
i am not happy with the example, but you can use it as a dark environment like that in the legendary 'Another World' Dos game. i have added a yellow sphere in the place of the light just as a guide. the light here are inside the tubes
move the camera inside the tube with keys and mouse
i will post in a minutes an example about the shadow .

Code: Select all

Enumeration
  #Window = 500
  #ground
  #Camera
  #Light1
  #Light2
  #sphere
  #plane
  #RedMaterial
  #YellowMaterial  
EndEnumeration

#CameraSpeed = 4
#RADIUS  = 20 ;tube thickness

Global bands = 8 ;number of points of every ring (circle)
#Rings = 2 ;number of Rings over all the tube Line (always 2, start ring and end ring)
Global divisions = 10
Structure vector3d
  x.f
  y.f
  z.f
EndStructure

Structure vertex
  x.f
  y.f
  z.f
EndStructure


Declare DrawTube (x.f, y.f,z.f, x2.f, y2.f, z2.f)
Declare LineXYZ (Line3D, x.f, y.f, z.f, x2.f, y2.f, z2.f)
Declare tubesCircle()

Global.f x0, y0
;Global tubeee
x0 = 0: y0 = 0
Define.f KeyX, KeyY, MouseX, MouseY

  
Procedure vector_cross(*v1.vector3d, *v2.vector3d, *vout.vector3d)
    *vout\x = (*v1\y * *v2\z) - (*v2\y * *v1\z)
    *vout\y = (*v1\z * *v2\x) - (*v2\z * *v1\x)
    *vout\z = (*v1\x * *v2\y) - (*v2\x * *v1\y)
EndProcedure

Procedure.f vector_magnitude(*v.vector3d)
    mag.f
    mag = Sqr(*v\x * *v\x + *v\y * *v\y + *v\z * *v\z)
    If mag = 0:mag = 1:EndIf
    ProcedureReturn mag
EndProcedure

Procedure vector_normalize (*v.vector3d)
    mag.f
    mag = vector_magnitude(*v)
    *v\x = *v\x / mag
    *v\y = *v\y / mag
    *v\z = *v\z / mag
EndProcedure


Procedure vector_add (*v1.vector3d, *v2.vector3d, *vout.vector3d)
    *vout\x = *v1\x + *v2\x
    *vout\y = *v1\y + *v2\y
    *vout\z = *v1\z + *v2\z
EndProcedure

Procedure vector_sub (*v1.vector3d, *v2.vector3d, *vout.vector3d)
    *vout\x = *v1\x - *v2\x
    *vout\y = *v1\y - *v2\y
    *vout\z = *v1\z - *v2\z
EndProcedure
  
  
    
Define.f KeyX, KeyY, MouseX, MouseY
Global tube

If InitEngine3D()
  
  ;Add3DArchive(".", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Models", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home+"Examples\3D\Data\GUI",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "Examples/3D/Data/Packs/desert.zip", #PB_3DArchive_Zip)
   
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)

If OpenWindow(#Window, 0, 0, DesktopW, DesktopH, "thick lines , W toggle wire/solid Frame ...., mouse and arrow keys to move/ rotate the camera ")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, DesktopW, DesktopH, 0, 0, 0)
    Parse3DScripts()
    OpenWindow3D(33,0,0,200,100,"Engine Stats")
    TextGadget3D(33,2,0,70,30,"")
    
    ShowGUI(255,0)
         
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, 200, 300, 150, #PB_Absolute)
    CameraLookAt(#Camera,0,0,0)
    CameraBackColor(#Camera, RGB(200,255,200))
    
    CreateMaterial(0, LoadTexture(0, "white.jpg"))
    DisableMaterialLighting(0, #False)
    SetMaterialColor(0, #PB_Material_AmbientColor, RGB(250, 255, 0))
    SetMaterialColor(0, #PB_Material_SpecularColor, RGB(255, 255, 0))

    CreateMaterial(1, LoadTexture(1, "MRAMOR6X6.jpg"))
    MaterialCullingMode(1, #PB_Material_NoCulling)

    CreateMaterial(2, LoadTexture(2, "ground_diffuse.png"))
    ;CreateMaterial(2, LoadTexture(2, "wood.jpg"))
    MaterialCullingMode(2, #PB_Material_NoCulling)
    DisableMaterialLighting(2, #False)
    SetMaterialColor(2, #PB_Material_AmbientColor, RGB(250, 255, 0))
    SetMaterialColor(2, #PB_Material_SpecularColor, RGB(255, 255, 0))
    
    CreateMaterial(0, LoadTexture(0, "wood.jpg"))
    DisableMaterialLighting(0, #True)
    
    GetScriptMaterial(#RedMaterial, "Color/Red")
    GetScriptMaterial(#YellowMaterial, "Color/Yellow")
    SetMaterialColor(#YellowMaterial, #PB_Material_SelfIlluminationColor, RGB(255,255,0))

    
    ;CreateLight(#Light1, RGB(255, 255, 255), 0, 20, 20)
    CreateLight(#Light1, RGB(255, 255, 255), 100, 0, -10)
    ;CreateLight(#Light2, RGB(255, 255, 255), 200, 100, 10)
    AmbientColor(RGB(100, 100, 100))
    CreateSphere(1222, 2); just a pointer to the light position
    CreateEntity(1222, MeshID(1222), MaterialID(#YellowMaterial), 100, 0, -10)
  EndIf
EndIf

CreateSphere(#sphere, 7)
CreateEntity(#sphere, MeshID(#sphere), MaterialID(#RedMaterial), 95, 14,0)
EntityPhysicBody(#sphere, #PB_Entity_SphereBody, 1,5,1)
WorldShadows(#PB_Shadow_Additive)
;WorldShadows(#PB_Shadow_Modulative)
CreateCube(#plane,1)
CreateEntity(#plane,MeshID(#plane),MaterialID(0), 0, -21, 0)
ScaleEntity(#plane, 300,1, 300)

wireFrame = 1

tubesCircle()
EntityPhysicBody(tube, #PB_Entity_StaticBody)

Repeat
  
  Event = WindowEvent()
        
      If ExamineMouse()
        MouseX = -MouseDeltaX()/20 
        MouseY = -MouseDeltaY()/20
      EndIf
      
          
      If ExamineKeyboard()
           
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
        
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
            MaterialShadingMode(2, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
            MaterialShadingMode(2, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
            
      EndIf
  
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
         
      RenderWorld()
      
            
      FlipBuffers()
      
      SetGadgetText3D(33,"FPS: "+StrF(Engine3DStatus(#PB_Engine3D_Current),2))
              
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
End

Procedure  DrawTube (x.f, y.f,z.f, x2.f, y2.f,z2.f)
  
  Dim vertx.vertex(10)
  lineVec.vector3d

   u.f: r.f
      
  txu.f : txv.f
   
  x1.f = x
  y1.f = y
  z1.f = z
  
  
  ;vector of the line between start vertex and the end vertex
  lineVec\x = x2 - x1
  lineVec\y = y2 - y1
  lineVec\z = z2 - z1
  
   
  tt.f = 0
  
  For i=0 To #Rings
        
       x = x1 + lineVec\x * tt 
      y = y1 + lineVec\y * tt 
      z = z1 + lineVec\z * tt
      tt + 1
      
       vertx(i)\x = x
       vertx(i)\y = y
       vertx(i)\z = z
       
   Next 
        
     current_point.vector3d
        next_point.vector3d
        T.vector3d
        B.vector3d
        N.vector3d
        p.f
     For i = 0 To #Rings-1
     
        ;center point
                
        current_point\x = vertx(i)\x
        current_point\y = vertx(i)\y
        current_point\z = vertx(i)\z
        ;next point For Frenet square
        
        next_point\x = vertx(i+1)\x
        next_point\y = vertx(i+1)\y
        next_point\z = vertx(i+1)\z

        ;T  = P' - P
        vector_sub(next_point, current_point, T)

        ;N = P' + P
        vector_add(next_point, current_point, N)

        ;B = T x N
        vector_cross(T, N, B)

        ;N = B x T
        vector_cross(B, T, N)

        ;Normalize vectors Or Else it won't work
        vector_normalize(B)
        vector_normalize(N)
        
        For j = 0 To bands
              new_point_x.f
              new_point_y.f
              
              ;rotate around the current point using normal rotation makes bands
            new_point_x = Sin(j * (#PI*2) / bands) * #RADIUS
            new_point_y = Cos(j * (#PI*2) / bands) * #RADIUS
            
                ;this is the coordinates of our point along the curve
            x = N\x * new_point_x + B\x * new_point_y + current_point\x
            y = N\y * new_point_x + B\y * new_point_y + current_point\y
            z = N\z * new_point_x + B\z * new_point_y + current_point\z
            
            MeshVertexPosition(x, y, z)
            MeshVertexTextureCoordinate(txu, txv)
            MeshVertexNormal(0, 1, 0)
            txv = txv + 1/#Rings
                         
         Next 
         txv = 0
         txu = txu + 1/bands
         
      Next 

      v.l
      For j = 0 To bands -1
          ;MeshFace(v,v+1,v + bands+1)
          ;MeshFace(v + bands+1,v + bands+2,v+1 )
          MeshFace(v,v + bands+1, v+1)
          MeshFace(v + bands+1,v + bands+2, v+1 )
         
          v + 1   
          
    Next 
         

  EndProcedure

  
  Procedure LineXYZ (Line3D, x.f, y.f,z.f, x2.f, y2.f,z2.f)
    
    
    tube = Line3D
    CreateMesh(tube , #PB_Mesh_TriangleList, #PB_Mesh_Dynamic )
    SetMeshMaterial(tube , MaterialID(2))
    ;; 0.00001 : necessary if all x,t,z are zero
    DrawTube (x+0.00001, y+0.00001, z+0.00001, x2, y2, z2)
    NormalizeMesh(tube)
    BuildMeshTangents(tube)
    FinishMesh(tube)
    
    CreateEntity(tube,MeshID(tube),MaterialID(2))
    EntityRenderMode(tube, 0)
    
  EndProcedure
  
  Procedure tubesCircle()
  For i=1 To divisions
    tubeee+1
      X.f=tempX.f:Z.f=tempZ.f
      X.f=X+#PI*2/divisions
      Z.f=Z+#PI*2/divisions
      XX.f=Cos(X)*100
      ZZ.f=Sin(Z)*100
      tempX.f=X: tempZ.f=Z
      
      X.f=X+#PI*2/divisions
      Z.f=Z+#PI*2/divisions
      XX2.f=Cos(X)*100
      ZZ2.f=Sin(Z)*100
      LineXYZ(tubeee,  xx,0,zz,  xx2, 0, zz2)
      
    Next
  EndProcedure
 
the test i have made to see the connections of a simple construction, some numbers are over each other but we can guess it, i may have errors it is an horrible task to connect vertices correctly . here i have used this LineXYZ(6, 0,1,-45, 0,7,-45, 15, 3, 3) here the red '3' determine it is a triangular tube:
LineXYZ(#mesh, x,y,z, x2,y2,z2, Radius.f, TubeShape, Material)

Code: Select all

#CameraSpeed = 1

#Rings = 2 ;number of Rings over all the Line (always 2, start ring and end ring)
#sphere = 17
#RedMaterial = 18


Global tube
Structure vector3d
  x.f
  y.f
  z.f
EndStructure

Structure vertex
  x.f
  y.f
  z.f
EndStructure

Dim vertx.vertex(32)

Declare DrawTube (x.f, y.f,z.f, x2.f, y2.f, z2.f, Radius.f, TubeShape)
Declare LineXYZ (Line3D, x.f, y.f, z.f, x2.f, y2.f, z2.f, Radius.f, TubeShape, Material)

    
Procedure vector_cross(*v1.vector3d, *v2.vector3d, *vout.vector3d)
    *vout\x = (*v1\y * *v2\z) - (*v2\y * *v1\z)
    *vout\y = (*v1\z * *v2\x) - (*v2\z * *v1\x)
    *vout\z = (*v1\x * *v2\y) - (*v2\x * *v1\y)
EndProcedure

Procedure.f vector_magnitude(*v.vector3d)
    mag.f
    mag = Sqr(*v\x * *v\x + *v\y * *v\y + *v\z * *v\z)
    If mag = 0:mag = 1:EndIf
    ProcedureReturn mag
EndProcedure

Procedure vector_normalize (*v.vector3d)
    mag.f
    mag = vector_magnitude(*v)
    *v\x = *v\x / mag
    *v\y = *v\y / mag
    *v\z = *v\z / mag
EndProcedure


Procedure vector_add (*v1.vector3d, *v2.vector3d, *vout.vector3d)
    *vout\x = *v1\x + *v2\x
    *vout\y = *v1\y + *v2\y
    *vout\z = *v1\z + *v2\z
EndProcedure

Procedure vector_sub (*v1.vector3d, *v2.vector3d, *vout.vector3d)
    *vout\x = *v1\x - *v2\x
    *vout\y = *v1\y - *v2\y
    *vout\z = *v1\z - *v2\z
EndProcedure

Define.f KeyX, KeyY, MouseX, MouseY

Enumeration
  #Window = 500
  #Plane
  #Camera
  #Light1
    
EndEnumeration

If InitEngine3D()
  
  Add3DArchive("\", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models", #PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts",#PB_3DArchive_FileSystem)
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/fonts", #PB_3DArchive_FileSystem)
    
  Parse3DScripts()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
ExamineDesktops()
DesktopW = DesktopWidth(0)
DesktopH = DesktopHeight(0)

If OpenWindow(#Window, 0, 0, DesktopW, DesktopH, "thick lines , W toggle wire/solid Frame ...., mouse and arrow keys to move/ rotate the camera ")
  If OpenWindowedScreen(WindowID(#Window), 0, 0, DesktopW, DesktopH, 0, 0, 0)
    
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, -40, 40, 30, #PB_Absolute)
    CameraLookAt(#Camera,1,10,-25)
    CameraBackColor(#Camera, RGB(200,200,200))
    
    CreateMaterial(0, LoadTexture(0, "white.jpg"))
    DisableMaterialLighting(0, #True)
    
    CreateMaterial(1, LoadTexture(1, "MRAMOR6X6.jpg"))
    MaterialCullingMode(1, #PB_Material_NoCulling)

    CreateMaterial(2, LoadTexture(2, "ground_diffuse.png"))
    MaterialCullingMode(2, #PB_Material_NoCulling)
    DisableMaterialLighting(2, #False)
        
    CreateMaterial(3, LoadTexture(3, "wood.jpg"))
    DisableMaterialLighting(3, #False)
    MaterialCullingMode(3, #PB_Material_NoCulling)
    MaterialShadingMode(3, #PB_Material_Wireframe)
    
    GetScriptMaterial(#RedMaterial, "Color/Red")
    
    CreateLight(#Light1, RGB(255, 255, 255), 0, 100, 20)
    AmbientColor(RGB(100, 100, 100))
  
  EndIf
EndIf
Global SphereMesh = CreateSphere(#PB_Any, 1)

CreatePlane(#plane, 600, 600, 100, 100, 100, 100)
CreateEntity(#plane,MeshID(#plane),MaterialID(1), 0, 0, 0)

glLineWidth_(5)
CreateLine3D(7, 0, 0.02, 0, RGB(255,   0,   0), 8,  0.02,  0, RGB(255,   0,   0))  ; Axis X
CreateLine3D(8, 0, 0, 0, RGB(  0, 255,   0),  0, 8,  0, RGB(  0, 255,   0))  ; Axis Y
CreateLine3D(9, 0, 0.02, 0, RGB(  0,   0, 255),  0,  0.02, 8, RGB(  0,   0, 255))  ; Axis Z

wireFrame = 1

;doc: draw thick lines from x,y,z to x2,y2,z2 with thickness Radius and TubeShape is the number of points makes the tube cross section polygon
;doc: LineXYZ(#mesh, x,y,z, x2,y2,z2, Radius.f, TubeShape, Material)

LineXYZ(6,  0,1,-45,  0,7,-45, 15, 3, 3)
;MoveEntity(tube, 0,18,-90) ;then we move it to any place so when it is rotating it is rotating correctly around itself 

WorldShadows(#PB_Shadow_Modulative)
WorldShadows(#PB_Shadow_Additive)
;MaterialShadingMode(3, #PB_Material_Solid)
Repeat
  
  Event = WindowEvent()
        
      If ExamineMouse()
        MouseX = -MouseDeltaX()/20 
        MouseY = -MouseDeltaY()/20
      EndIf
      
          
      If ExamineKeyboard()
           
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed
        Else
          KeyY = 0
        EndIf
        
        If KeyboardReleased(#PB_Key_W)
          If wireFrame
            MaterialShadingMode(2, #PB_Material_Wireframe)
          wireFrame ! 1
        Else 
            MaterialShadingMode(2, #PB_Material_Solid)
          wireFrame ! 1
        EndIf
        EndIf
            
      EndIf
  
      RotateCamera(#Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera(#Camera, KeyX, 0, KeyY)
      ;RotateEntity(tube, 0,1,0, #PB_Relative)
      RenderWorld()
      
            
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
    
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
  
End

Procedure  DrawTube (x.f, y.f,z.f, x2.f, y2.f,z2.f, Radius.f, TubeShape)
  
  Dim vertx.vertex(10)
  lineVec.vector3d

   u.f: r.f
      
  txu.f : txv.f
   
  x1.f = x
  y1.f = y
  z1.f = z
  
  bands = TubeShape
    
  ;vector of the line between start vertex and the end vertex
  lineVec\x = x2 - x1
  lineVec\y = y2 - y1
  lineVec\z = z2 - z1
  
  
   ;Dist.f = Sqr(lineVec\x*lineVec\x + lineVec\y*lineVec\y + lineVec\z*lineVec\z)
  ;Debug Dist
  tt.f = 0
  
  For i=0 To #Rings
        
       x = x1 + lineVec\x * tt 
      y = y1 + lineVec\y * tt 
      z = z1 + lineVec\z * tt
      tt + 1
      
       vertx(i)\x = x
       vertx(i)\y = y
       vertx(i)\z = z
       
   Next 
        
     current_point.vector3d
        next_point.vector3d
        T.vector3d
        B.vector3d
        N.vector3d
        p.f
     For i = 0 To #Rings-1
     
        ;center point
                
        current_point\x = vertx(i)\x
        current_point\y = vertx(i)\y
        current_point\z = vertx(i)\z
        ;next point For Frenet square
        
        next_point\x = vertx(i+1)\x
        next_point\y = vertx(i+1)\y
        next_point\z = vertx(i+1)\z

        ;T  = P' - P
        vector_sub(next_point, current_point, T)

        ;N = P' + P
        vector_add(next_point, current_point, N)

        ;B = T x N
        vector_cross(T, N, B)

        ;N = B x T
        vector_cross(B, T, N)

        ;Normalize vectors Or Else it won't work
        vector_normalize(B)
        vector_normalize(N)
        
        For j = 0 To bands
              new_point_x.f
              new_point_y.f
              
              ;rotate around the current point using normal rotation makes bands
            new_point_x = Sin(j * (#PI*2) / bands) * Radius
            new_point_y = Cos(j * (#PI*2) / bands) * Radius
            
                ;this is the coordinates of our point along the curve
            x = N\x * new_point_x + B\x * new_point_y + current_point\x
            y = N\y * new_point_x + B\y * new_point_y + current_point\y
            z = N\z * new_point_x + B\z * new_point_y + current_point\z
            
            MeshVertexPosition(x, y, z)
            MeshVertexTextureCoordinate(txu, txv)
            MeshVertexNormal(1, 1, 1)
            
            ;Sphere = CreateEntity(#PB_Any, MeshID(SphereMesh), #PB_Material_None , x,y,z)
            
            CreateText3D(txt, Str(txt))
            Text3DColor(txt, RGBA(255, 0, 0, 255))
            Text3DAlignment(txt, #PB_Text3D_HorizontallyCentered)
            ;AttachEntityObject(txt, "", Text3DID(txt))
            xv=xv+x+0.1
            MoveText3D(txt, x, y, z)
            txt+1
            
            txv = txv + 1/#Rings
                         
         Next 
         txv = 0
         txu = txu + 1/bands
         
      Next 

      v.l
      Debug "the connections of the vertices"
      For j = 0 To bands -1
          MeshFace(v,v + bands+1, v+1)
          MeshFace(v + bands+1, v + bands+2, v+1 )
          
          Debug Str(v)+"  "+Str(v + bands+1)+"   "+Str(v+1)
          Debug Str(v+bands+1)+"  "+Str(v+bands+2)+"   "+Str(v+1)
          v + 1   
          
      Next 
 
  EndProcedure
  
  Procedure LineXYZ (Line3D, x.f, y.f,z.f, x2.f, y2.f,z2.f, Radius.f, TubeShape, Material)
    
    x.f+0.00001 : y.f+0.00001 : z.f+0.00001 ; i don't know why 0.00001 is necessary
    x2.f+0.00001 : y2.f+0.00001 : z2.f+0.00001 ; if x,y,z or x2,y2,z2 are zero !!!
    
    tube = Line3D + 2000 
    CreateMesh(tube , #PB_Mesh_TriangleList, #PB_Mesh_Dynamic )
    ;SetMeshMaterial(tube , MaterialID(Material))
    ;; 0.00001 : necessary if all x,t,z are zero
    DrawTube (x+0.00001, y+0.00001, z+0.00001, x2, y2, z2, Radius, TubeShape)
    NormalizeMesh(tube)
    BuildMeshTangents(tube)
    FinishMesh(tube)
    ;NormalizeMesh(tube)
    ;BuildMeshTangents(tube)
    CreateEntity(tube,MeshID(tube),MaterialID(Material))
    ;AttachEntityObject(Line3D,"",EntityID(tube))
    
      
    
  EndProcedure
  
 
 

Re: Circular Tube ( UFO ) & Conical and Pyramidal tubes

Posted: Fri Jan 09, 2015 7:08 pm
by falsam
I hope that I have correctly translated your sentence. :oops:

You say
applePi wrote:i think the vertices are connected clockwise on one of the triangles and it should be counter clockwise.
I thought he was connecting vertices in the opposite direction of clockwise ?

Code: Select all

Global Distance.f = 5, Height = 1

InitEngine3D()
InitKeyboard()
InitSprite()

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

Window = OpenWindow(#PB_Any,0,0,1024,768,"Vertex")
OpenWindowedScreen(WindowID(window),0,0,1024,768)

;Light & Shadow
AmbientColor(RGB(127, 127, 127))
CreateLight(#PB_Any,RGB(151, 251, 151), -3, 10, 10)
WorldShadows(#PB_Shadow_Additive)

;Camera 
Camera = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera, RGB(145, 182, 201))
MoveCamera(Camera, 2, 5, 15, #PB_Absolute)  
CameraLookAt(Camera, 0,0,0)   

; Axes X,Y,Z 
CreateLine3D(#PB_Any, -20, 0, 0, Red, 20, 0, 0, RGB(255, 0, 0)) ; Red 
CreateLine3D(#PB_Any, 0,-20,0, Green, 0, 20, 0, RGB(0, 255, 0)); Green 
CreateLine3D(#PB_Any, 0,0,-20, Blue, 0, 0, 20, RGB(0, 255, 255)) ;Blue 

;Sandbox
Material = CreateMaterial(#PB_Any, TextureID(LoadTexture(#PB_Any, "MRAMOR6X6.jpg")))
CreateEntity(#PB_Any, MeshID(CreatePlane(#PB_Any, 10, 10, 1, 1, 3, 3)), MaterialID(Material), 0, -0.1, 0)

;LandMark (Camera turn around use <-- or -->)
LandMark = CreateEntity(#PB_Any, MeshID(CreateSphere(#PB_Any, 0.001)), #PB_Material_None)

;Mesh create one face
Mesh = CreateMesh(#PB_Any, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)

;Vertex 0
Entity = CreateEntity(#PB_Any, MeshID(CreateSphere(#PB_Any, 0.01)), #PB_Material_None, 0, 1, 0)
Text = CreateText3D(#PB_Any, "0") : ScaleText3D(Text, 0.2,0.2,0.2,#PB_Absolute)
AttachEntityObject(Entity, "", Text3DID(Text))

MeshVertexPosition(0, 1, 0)
MeshVertexNormal(0, 1, 0)
MeshVertexTextureCoordinate(0, 0) 

;Vertex 1
Entity = CreateEntity(#PB_Any, MeshID(CreateSphere(#PB_Any, 0.01)), #PB_Material_None, 0, 0, 0)
Text = CreateText3D(#PB_Any, "1") : ScaleText3D(Text, 0.2,0.2,0.2,#PB_Absolute)
AttachEntityObject(Entity, "", Text3DID(Text))

MeshVertexPosition(0, 0, 0)
MeshVertexNormal(0, 1, 0)
MeshVertexTextureCoordinate(0, 1) 

;Vertex 2
Entity = CreateEntity(#PB_Any, MeshID(CreateSphere(#PB_Any, 0.01)), #PB_Material_None, 1, 0, 0)
Text = CreateText3D(#PB_Any, "2") : ScaleText3D(Text, 0.2,0.2,0.2,#PB_Absolute)
AttachEntityObject(Entity, "", Text3DID(Text))

MeshVertexPosition(1, 0, 0)
MeshVertexNormal(0, 1, 0)
MeshVertexTextureCoordinate(1, 1) 

;Vertex 3
Entity = CreateEntity(#PB_Any, MeshID(CreateSphere(#PB_Any, 0.01)), #PB_Material_None, 1, 1, 0)
Text = CreateText3D(#PB_Any, "3") : ScaleText3D(Text, 0.2,0.2,0.2,#PB_Absolute)
AttachEntityObject(Entity, "", Text3DID(Text))

MeshVertexPosition(1, 1, 0)
MeshVertexNormal(0, 1, 0)
MeshVertexTextureCoordinate(0, 1) 

;Create triangle (vertices in the opposite direction of clockwise)
MeshFace(0, 1, 2)
MeshFace(0, 2, 3)

NormalizeMesh(Mesh)
BuildMeshTangents(Mesh)
FinishMesh(#True)

Texture = LoadTexture(#PB_Any, "Dirt.jpg")
Material = CreateMaterial(#PB_Any, TextureID(Texture))

Entity = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(material))

Repeat
  Repeat
    Event  = WindowEvent()
    Select Event
      Case #PB_Event_CloseWindow
        End
        
    EndSelect
  Until Event = 0
  
  If ExamineKeyboard()
    
    If KeyboardPushed (#PB_Key_Escape)
      Break
    EndIf
  EndIf
  
  If KeyboardPushed (#PB_Key_Left) 
    RotateEntity(LandMark, 0, -2, 0, #PB_Relative) 
  EndIf
  
  If KeyboardPushed (#PB_Key_Right) 
    RotateEntity(LandMark, 0, 2, 0, #PB_Relative) 
  EndIf
  
  If KeyboardPushed (#PB_Key_Up) 
    Distance - 0.1
  EndIf
  
  If KeyboardPushed (#PB_Key_Down) 
    Distance + 0.1
  EndIf
  
  CameraFollow(Camera, EntityID(LandMark), 0, EntityY(LandMark)+Height, Distance, 0.05, 0.05, #True)
  
  RenderWorld(80)
  FlipBuffers()  
  
ForEver
I have no problem with shadows, and light on the mesh looks good.

Use left, right, up and down keys to turn around the mesh. Thank for your codes :)


[Edit] I saw your second post after having answered. Thanks:)