Cone, Torus & Pyramid

Everything related to 3D programming
User avatar
falsam
Enthusiast
Enthusiast
Posts: 632
Joined: Wed Sep 21, 2011 9:11 am
Location: France
Contact:

Cone, Torus & Pyramid

Post by falsam »

Hello. Who wrote a procedure to create a Cone a Torus and a Pyramid? Thanks
Last edited by falsam on Wed Jan 07, 2015 12:02 pm, edited 2 times in total.

➽ Windows 11 64-bit - PB 6.21 x64 - AMD Ryzen 7 - NVIDIA GeForce GTX 1650 Ti

Sorry for my bad english and the Dunning–Kruger effect 🤪
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Cone and Torus

Post by StarBootics »

Hi falsam,

I have one procedure for both of them, unfortunately they are embedded in a prcedure for a mesh editor program I have worked on 3 years ago but abandon the project due to lack of money to buy an OpenGL reference book and no more time to spend on that project.

If you can wait few days I think I can take the code and adapt it to OGRE engine but this will take some time.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
falsam
Enthusiast
Enthusiast
Posts: 632
Joined: Wed Sep 21, 2011 9:11 am
Location: France
Contact:

Re: Cone and Torus

Post by falsam »

falsam wrote:If you can wait few days I think I can take the code and adapt it to OGRE engine but this will take some time.
no problem. Thank.

➽ Windows 11 64-bit - PB 6.21 x64 - AMD Ryzen 7 - NVIDIA GeForce GTX 1650 Ti

Sorry for my bad english and the Dunning–Kruger effect 🤪
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Cone and Torus

Post by StarBootics »

Hi again,

Ok this is the torus example. The Cone example will follow soon.

Best regards
StarBootics

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : OGRE - CreateTorus()
; File Name : OGRE - CreateTorus.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 06-01-2015
; Last Update : 06-01-2015
; PureBasic code : V5.31
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Macro LinearlySpacedValue(IncrementID, IncrementMax, MinValue, MaxValue)
  
   ((MinValue) + ((MaxValue) - (MinValue)) * ((IncrementID) / (IncrementMax)))

EndMacro

Macro CalculateTorusVertex(MinorRadius, MajorRadius, Uxx, Vxx)
  
  MeshVertexPosition((MajorRadius + MinorRadius * Cos(Vxx)) * Cos(Uxx), (MajorRadius + MinorRadius * Cos(Vxx)) * Sin(Uxx), MinorRadius * Sin(Vxx))
  MeshVertexTextureCoordinate(Uxx / (2*#PI), Vxx / (2*#PI))
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Create Torus Mesh <<<<<

Procedure CreateTorus(MeshID, MinorRadius.f, MajorRadius.f, Meridian = 32, Parallel = 32)
  
  MeshHandle = CreateMesh(MeshID)
  
  If MeshID = #PB_Any
    MeshID = MeshHandle
  EndIf
  
  If IsMesh(MeshID)
    
    AddSubMesh()
    
    If Meridian < 3
      Meridian = 3
    EndIf
    
    If Parallel < 3
      Parallel = 3
    EndIf
    
    P00 = 0
    P01 = P00 + 1
    P02 = P01 + 1
    P03 = P02 + 1

    For MeridianID = 0 To Meridian - 1
      
      U00.d = LinearlySpacedValue(MeridianID, Meridian, 0.0, 2.0 * #PI)
      U01.d = LinearlySpacedValue(MeridianID + 1, Meridian, 0.0, 2.0 * #PI)
      
      For ParallelID = 0 To Parallel - 1
        
        V00.d = LinearlySpacedValue(ParallelID, Parallel, 0.0, 2.0 * #PI)
        V01.d = LinearlySpacedValue(ParallelID + 1, Parallel, 0.0, 2.0 * #PI)

        CalculateTorusVertex(MinorRadius, MajorRadius, U00, V00) ; P00
        CalculateTorusVertex(MinorRadius, MajorRadius, U01, V00) ; P01
        CalculateTorusVertex(MinorRadius, MajorRadius, U01, V01) ; P02
        CalculateTorusVertex(MinorRadius, MajorRadius, U00, V01) ; P03
        
        MeshFace(P00, P01, P02)
        MeshFace(P02, P03, P00)
        
        P00 = P03 + 1
        P01 = P00 + 1
        P02 = P01 + 1
        P03 = P02 + 1

      Next
      
    Next
    
    NormalizeMesh(MeshID, 0)
    BuildMeshTangents(MeshID)
    
    FinishMesh(1)
    
  EndIf
  
  ProcedureReturn MeshID
EndProcedure

#CameraSpeed = 3

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

Define.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    ; Create a Torus
    CreateTorus(1, 2.0, 5.00)
    
    
    CreateMaterial(0, LoadTexture(0, "clouds.jpg"))
    SetMaterialColor(0, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    
    
    CreateEntity(0, MeshID(1), MaterialID(0))
    
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 0, 100, #PB_Absolute)
    
    
    Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      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
        
      EndIf
      
      RotateEntity(0, 1, 1, 1, #PB_Relative)
      
      RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera  (0, KeyX, 0, KeyY)
      
      RenderWorld()
      Screen3DStats()      
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
The Stone Age did not end due to a shortage of stones !
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Cone and Torus

Post by StarBootics »

Hi again,

Ok this is the Limpet Torus example (almost identical to the regular torus)

Regards
StarBootics

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : OGRE - CreateLimpetTorus()
; File Name : OGRE - CreateLimpetTorus.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 06-01-2015
; Last Update : 06-01-2015
; PureBasic code : V5.31
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

Macro LinearlySpacedValue(IncrementID, IncrementMax, MinValue, MaxValue)
  
   ((MinValue) + ((MaxValue) - (MinValue)) * ((IncrementID) / (IncrementMax)))

EndMacro

Macro LimpetTorusSurface(P_Root, P_u, P_v, Uxx, Vxx)
  
  MeshVertexPosition(Cos(P_u) / (Sqr(P_Root) + Sin(P_v)), Sin(P_u) / (Sqr(P_Root) + Sin(P_v)), 1 / (Sqr(P_Root) + Cos(P_v)))
  MeshVertexTextureCoordinate(Uxx, Vxx)
  
EndMacro

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Create Torus Mesh <<<<<

Procedure CreateLimpetTorus(MeshID, Root.f, Division = 32)
  
  MeshHandle = CreateMesh(MeshID)
  
  If MeshID = #PB_Any
    MeshID = MeshHandle
  EndIf
  
  If IsMesh(MeshID)
    
    AddSubMesh()
    
    If Division < 16
      Division = 16
    EndIf
    
    
    P00 = 0
    P01 = P00 + 1
    P02 = P01 + 1
    P03 = P02 + 1
    
    For Division_V_ID = 0 To Division - 1
      
      V00.d = LinearlySpacedValue(Division_V_ID, Division, -#PI, #PI)
      V01.d = LinearlySpacedValue(Division_V_ID + 1, Division, -#PI, #PI)
      VV00.d = LinearlySpacedValue(Division_V_ID, Division, 0.0, 1.0) 
      VV01.d = LinearlySpacedValue(Division_V_ID + 1, Division, 0.0, 1.0) 
      
      For Division_U_ID = 0 To Division - 1
        
        U00.d = LinearlySpacedValue(Division_U_ID, Division, -#PI, #PI)
        U01.d = LinearlySpacedValue(Division_U_ID + 1, Division, -#PI, #PI)
        UU00.d = LinearlySpacedValue(Division_U_ID, Division, 0.0, 1.0) 
        UU01.d = LinearlySpacedValue(Division_U_ID + 1, Division, 0.0, 1.0) 
        
        LimpetTorusSurface(Root, U00, V00, UU00, VV00)
        LimpetTorusSurface(Root, U01, V00, UU01, VV00)
        LimpetTorusSurface(Root, U01, V01, UU01, VV01)
        LimpetTorusSurface(Root, U00, V01, UU00, VV01)
        
        
        MeshFace(P02, P01, P00)
        MeshFace(P00, P03, P02)
        
        P00 = P03 + 1
        P01 = P00 + 1
        P02 = P01 + 1
        P03 = P02 + 1
        
      Next
      
    Next
    
    NormalizeMesh(MeshID, 0)
    BuildMeshTangents(MeshID)
    
    FinishMesh(1)
    
  EndIf
  
  ProcedureReturn MeshID
EndProcedure

#CameraSpeed = 3

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

Define.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
  
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    
    ; Create a Limpet Torus
    CreateLimpetTorus(1, 2.5)
    
    
    CreateMaterial(0, LoadTexture(0, "clouds.jpg"))
    SetMaterialColor(0, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
    
    
    CreateEntity(0, MeshID(1), MaterialID(0))
    
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 0, 10, #PB_Absolute)
    
    
    Repeat
      Screen3DEvents()
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      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
        
      EndIf
      
      RotateEntity(0, 1, 1, 1, #PB_Relative)
      
      RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera  (0, KeyX, 0, KeyY)
      
      RenderWorld()
      Screen3DStats()      
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
The Stone Age did not end due to a shortage of stones !
User avatar
VB6_to_PBx
Enthusiast
Enthusiast
Posts: 627
Joined: Mon May 09, 2011 9:36 am

Re: Cone and Torus

Post by VB6_to_PBx »

very nice examples , especially the Limpet Torus

thanks
 
PureBasic .... making tiny electrons do what you want !

"With every mistake we must surely be learning" - George Harrison
User avatar
falsam
Enthusiast
Enthusiast
Posts: 632
Joined: Wed Sep 21, 2011 9:11 am
Location: France
Contact:

Re: Cone and Torus

Post by falsam »

StarBootics many thanks :)

I tested the creation of torus and it is beautiful. But there is a light problem.

Compare the light on the cube, the ball and the torus.

Code: Select all

Enumeration
  #Mainform
EndEnumeration

Global Event

Macro LinearlySpacedValue(IncrementID, IncrementMax, MinValue, MaxValue)
   ((MinValue) + ((MaxValue) - (MinValue)) * ((IncrementID) / (IncrementMax)))
EndMacro

;CreateTorus() - By StarBootics
Macro CalculateTorusVertex(MinorRadius, MajorRadius, Uxx, Vxx)
  MeshVertexPosition((MajorRadius + MinorRadius * Cos(Vxx)) * Cos(Uxx), (MajorRadius + MinorRadius * Cos(Vxx)) * Sin(Uxx), MinorRadius * Sin(Vxx))
  MeshVertexTextureCoordinate(Uxx / (2*#PI), Vxx / (2*#PI))
EndMacro

Procedure CreateTorus(MeshID, MinorRadius.f, MajorRadius.f, Meridian = 32, Parallel = 32)
  Protected MeshHandle, P00, P01, P02, P03, MeridianID, U00.d, U01.d, ParallelID, V00.d, V01.d
  
  MeshHandle = CreateMesh(MeshID, #PB_Mesh_TriangleList, #PB_Mesh_Dynamic)
  
  If MeshID = #PB_Any
    MeshID = MeshHandle
  EndIf
  
  If IsMesh(MeshID)
    
    AddSubMesh()
    
    If Meridian < 3
      Meridian = 3
    EndIf
    
    If Parallel < 3
      Parallel = 3
    EndIf
    
    P00 = 0
    P01 = P00 + 1
    P02 = P01 + 1
    P03 = P02 + 1

    For MeridianID = 0 To Meridian - 1
      
      U00 = LinearlySpacedValue(MeridianID, Meridian, 0.0, 2.0 * #PI)
      U01 = LinearlySpacedValue(MeridianID + 1, Meridian, 0.0, 2.0 * #PI)
      
      For ParallelID = 0 To Parallel - 1
        
        V00 = LinearlySpacedValue(ParallelID, Parallel, 0.0, 2.0 * #PI)
        V01 = LinearlySpacedValue(ParallelID + 1, Parallel, 0.0, 2.0 * #PI)

        CalculateTorusVertex(MinorRadius, MajorRadius, U00, V00) ; P00
        CalculateTorusVertex(MinorRadius, MajorRadius, U01, V00) ; P01
        CalculateTorusVertex(MinorRadius, MajorRadius, U01, V01) ; P02
        CalculateTorusVertex(MinorRadius, MajorRadius, U00, V01) ; P03
        
        MeshFace(P00, P01, P02)
        MeshFace(P02, P03, P00)
        
        P00 = P03 + 1
        P01 = P00 + 1
        P02 = P01 + 1
        P03 = P02 + 1

      Next
      
    Next
    
    NormalizeMesh(MeshID, 0)
    BuildMeshTangents(MeshID)
    
    FinishMesh(#True)
    
  EndIf
  
  ProcedureReturn MeshID
EndProcedure

InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()

OpenWindow(#Mainform, 0, 0, 1024, 768, "Create Torus", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Mainform),0, 0, 1024, 768)

KeyboardMode(#PB_Keyboard_International)
 
;Light & Shadow
AmbientColor(RGB(127, 127, 127))
CreateLight(#PB_Any,RGB(151, 251, 151), -4, 50, 5)
WorldShadows(#PB_Shadow_Additive)

;Camera 
Camera = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera, RGB(145, 182, 201))

MoveCamera(Camera, 10, 10, 15, #PB_Absolute)  
CameraLookAt(Camera, 0,0,0)   

;Material
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
CreateMaterial(0, TextureID(LoadTexture(#PB_Any, "Dirt.jpg")))
CreateMaterial(1, TextureID(LoadTexture(#PB_Any, "MRAMOR6X6.jpg")))

;Entities
CreateEntity(#PB_Any, MeshID(CreatePlane(#PB_Any, 30, 30, 10, 10, 5, 5)), MaterialID(0))
CreateEntity(#PB_Any, MeshID(CreateCube(#PB_Any, 4)), MaterialID(1), -6, 3, 0)
CreateEntity(#PB_Any, MeshID(CreateSphere(#PB_Any, 2)), MaterialID(1), 0, 3, 0)
CreateEntity(#PB_Any, MeshID(CreateTorus(#PB_Any, 1, 2)), MaterialID(1), 6, 3, 0)

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
  
  RenderWorld(80)
  FlipBuffers()  
  
ForEver
Last edited by falsam on Wed Jan 07, 2015 7:38 pm, edited 1 time in total.

➽ Windows 11 64-bit - PB 6.21 x64 - AMD Ryzen 7 - NVIDIA GeForce GTX 1650 Ti

Sorry for my bad english and the Dunning–Kruger effect 🤪
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Cone, Torus & Pyramid

Post by Samuel »

The torus lacks vertex normals which are used for light calculations.
There's no need to calculate the normals because he uses NormalizeMesh(), but they still need to exist in order for that command to work properly.

Replace the CalculateTorusVertex macro with this and then the problem should be fixed.

Code: Select all

Macro CalculateTorusVertex(MinorRadius, MajorRadius, Uxx, Vxx)
  MeshVertexPosition((MajorRadius + MinorRadius * Cos(Vxx)) * Cos(Uxx), (MajorRadius + MinorRadius * Cos(Vxx)) * Sin(Uxx), MinorRadius * Sin(Vxx))
  MeshVertexNormal(0, 1, 0)
  MeshVertexTextureCoordinate(Uxx / (2*#PI), Vxx / (2*#PI))
EndMacro
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Cone, Torus & Pyramid

Post by StarBootics »

Hi falsam,

Your example don't work on linux as is, I got texture not initialized on line 104. I don't understand why your code is working on Window but not on Linux even if I have change the path in the Add3DArchive() instruction.

Anyway, about the light problem, I don't know about what NormalizeMesh() and BuildMeshTangents() does exactly on the mesh. But the way the torus mesh is built we have some vertex on the same 3D spot and we have two normals for the same point on the surface (the mesh approximate the surface) and this can be source of the problem.

If it is confirm the Torus generation procedure will be more complex and I'm not quit sure about how to do it.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Cone, Torus & Pyramid

Post by Samuel »

StarBootics wrote: Anyway, about the light problem, I don't know about what NormalizeMesh() and BuildMeshTangents() does exactly on the mesh.
NormalizeMesh() calculates the normal vectors for each vertex based on the mesh shape.
In other words you can add a random normal vector to each vertex and then use NormalizeMesh() to auto calculate the correct vectors.

BuildMeshTangents() is similar to NormalizeMesh(), but instead calculates the tangent vectors. This is a common requirement for graphic shaders.
StarBootics wrote: But the way the torus mesh is built we have some vertex on the same 3D spot and we have two normals for the same point on the surface (the mesh approximate the surface) and this can be source of the problem.
This shouldn't be a problem as long as each vertex has a separate normal (even if the vertices and normals are exact duplicates). When you start adding multiple normals to a single vertex some of the normals will be excluded which could cause lighting issues.
User avatar
falsam
Enthusiast
Enthusiast
Posts: 632
Joined: Wed Sep 21, 2011 9:11 am
Location: France
Contact:

Re: Cone, Torus & Pyramid

Post by falsam »

Sorry StarBootics. Linux is case sensitive. I replaced "Examples" by "examples". I think my code works.

@Samuel: Yeahhhhh thank you for your participation. When I apply your changes, the light is correct.

➽ Windows 11 64-bit - PB 6.21 x64 - AMD Ryzen 7 - NVIDIA GeForce GTX 1650 Ti

Sorry for my bad english and the Dunning–Kruger effect 🤪
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Cone, Torus & Pyramid

Post by StarBootics »

falsam wrote:When I apply your changes, the light is correct.
Is the shadow is smooth ? Because on the sphere and the cube the shadow is smooth but on the torus is everything but smooth.

StarBootics
The Stone Age did not end due to a shortage of stones !
User avatar
Samuel
Enthusiast
Enthusiast
Posts: 755
Joined: Sun Jul 29, 2012 10:33 pm
Location: United States

Re: Cone, Torus & Pyramid

Post by Samuel »

The shadows on the sphere are also blocky, but it can be harder to spot depending on the amount of vertices. It's even more noticeable if you use the #PB_Shadow_Modulative type.
This is just how stencil based shadows work. There isn't much you can do about it unless you swap to shader based shadows (not possible in Purebasic, yet).

I tweaked your example a little bit. The NormalizeMesh() command was done inside the mesh creation, but it needed to be done after mesh creation.

You'll notice that the torus won't look very smooth now and that's because you created the mesh for flat shading.
In order to do smooth shading you don't want to double up on vertices. You only want one vertex and normal per position.
Then you will have a smooth shaded torus, but the shadows will still be blocky because of the reason I specified earlier.

Code: Select all

Macro LinearlySpacedValue(IncrementID, IncrementMax, MinValue, MaxValue)
   ((MinValue) + ((MaxValue) - (MinValue)) * ((IncrementID) / (IncrementMax)))
EndMacro

;CreateTorus() - By StarBootics
Macro CalculateTorusVertex(MinorRadius, MajorRadius, Uxx, Vxx)
  MeshVertexPosition((MajorRadius + MinorRadius * Cos(Vxx)) * Cos(Uxx), (MajorRadius + MinorRadius * Cos(Vxx)) * Sin(Uxx), MinorRadius * Sin(Vxx))
  MeshVertexNormal(0, 1, 0)
  MeshVertexTextureCoordinate(Uxx / (2*#PI), Vxx / (2*#PI))
EndMacro

Procedure CreateTorus(MinorRadius.f, MajorRadius.f, Meridian = 32, Parallel = 32)
  
  Protected Handle, P00, P01, P02, P03, MeridianID, U00.d, U01.d, ParallelID, V00.d, V01.d
 
  Handle = CreateMesh(#PB_Any)
 
  If Meridian < 3
    Meridian = 3
  EndIf
   
  If Parallel < 3
    Parallel = 3
  EndIf
   
  P00 = 0
  P01 = P00 + 1
  P02 = P01 + 1
  P03 = P02 + 1

  For MeridianID = 0 To Meridian - 1
     
    U00 = LinearlySpacedValue(MeridianID, Meridian, 0.0, 2.0 * #PI)
    U01 = LinearlySpacedValue(MeridianID + 1, Meridian, 0.0, 2.0 * #PI)
     
    For ParallelID = 0 To Parallel - 1
       
      V00 = LinearlySpacedValue(ParallelID, Parallel, 0.0, 2.0 * #PI)
      V01 = LinearlySpacedValue(ParallelID + 1, Parallel, 0.0, 2.0 * #PI)

      CalculateTorusVertex(MinorRadius, MajorRadius, U00, V00) ; P00
      CalculateTorusVertex(MinorRadius, MajorRadius, U01, V00) ; P01
      CalculateTorusVertex(MinorRadius, MajorRadius, U01, V01) ; P02
      CalculateTorusVertex(MinorRadius, MajorRadius, U00, V01) ; P03
       
      MeshFace(P00, P01, P02)
      MeshFace(P02, P03, P00)
       
      P00 = P03 + 1
      P01 = P00 + 1
      P02 = P01 + 1
      P03 = P02 + 1

    Next
    
  Next
   
  FinishMesh(#True)
  
  NormalizeMesh(Handle)
  BuildMeshTangents(Handle)
  
  ProcedureReturn Handle
  
EndProcedure

If InitEngine3D() = 0
  End
EndIf
If InitKeyboard() = 0
  End
EndIf
If InitSprite() = 0
  End
EndIf

Enumeration
  #Window
  #Camera
  #Light
  #Node
  #Texture
  #Material
  #Mesh
  #Plane
  #Torus
  #Cube
  #Sphere
EndEnumeration

If OpenWindow(#Window, 0, 0, 1024, 768, "Create Torus", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If OpenWindowedScreen(WindowID(#Window),0, 0, 1024, 768)

    KeyboardMode(#PB_Keyboard_International)
    
    ; TEXTURE
    CreateTexture(#Texture, 256, 256)
    StartDrawing(TextureOutput(#Texture))
      Box(  0,   0, 128, 128, RGB(200,200,200))
      Box(128,   0, 128, 128, RGB(100,100,255))
      Box(  0, 128, 128, 128, RGB(100,100,255))
      Box(128, 128, 128, 128, RGB(200,200,200))
    StopDrawing()
    
    ; MATERIAL
    CreateMaterial(#Material, TextureID(#Texture))
    
    ; ENTITIES
    CreatePlane(#Mesh, 30, 30, 10, 10, 5, 5)
    CreateEntity(#Plane, MeshID(#Mesh), MaterialID(#Material))
    
    CreateCube(#Mesh, 4)
    CreateEntity(#Cube, MeshID(#Mesh), MaterialID(#Material), -6, 3, 0)
    
    CreateSphere(#Mesh, 2)
    CreateEntity(#Sphere, MeshID(#Mesh), MaterialID(#Material), 0, 3, 0)
    
    MeshHandle = CreateTorus(1, 2)
    If IsMesh(MeshHandle) <> 0
      CreateEntity(#Torus, MeshID(MeshHandle), MaterialID(#Material), 6, 3, 0)
    EndIf
    
    ; LIGHT
    CreateLight(#Light, RGB(150, 150, 150), 0, 10, 12)
    
    ; SHADOW
    WorldShadows(#PB_Shadow_Additive)
    ;WorldShadows(#PB_Shadow_Modulative)
    
    ; NODE
    CreateNode(#Node, 0, 0, 0)
    AttachNodeObject(#Node, LightID(#Light))
    
    ; CAMERA
    CreateCamera(#Camera, 0, 0, 100, 100)
    MoveCamera(#Camera, 10, 10, 15, #PB_Absolute) 
    CameraLookAt(#Camera, 0, 0, 0)
    CameraBackColor(#Camera, RGB(30, 30, 30))

    Repeat
  
      Event = WindowEvent()
  
      ExamineKeyboard()

      RotateNode(#Node, 0, 1, 0, #PB_Relative)
  
      FlipBuffers()
      RenderWorld()
 
    Until Event = #PB_Event_CloseWindow Or KeyboardReleased(#PB_Key_Escape)

  EndIf
EndIf
End
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Cone, Torus & Pyramid

Post by StarBootics »

Hello everyone,

I still have some problem with the cone, for the time being this the Tetrahedron.

StarBootics

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : OGRE - CreateTetrahedron()
; File Name : OGRE - CreateTetrahedron.pb
; File version: 1.0.0
; Programming : OK
; Programmed by : StarBootics
; Date : 09-01-2015
; Last Update : 10-01-2015
; PureBasic code : V5.31
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; <<<<< Create Tetrahedron Mesh <<<<<

Procedure CreateTetrahedron(MeshID, Size.f)
  
  MeshHandle = CreateMesh(MeshID)
  
  If MeshID = #PB_Any
    MeshID = MeshHandle
  EndIf
  
  If IsMesh(MeshID)
    
    AddSubMesh()
    
    ; <<<<<<<<<<<<<<<<<<<<
    ; <<<<< 1st face <<<<<
    
    MeshVertexPosition(0.000000, -0.333333,  0.942809)
    MeshVertexTextureCoordinate(0.250000, 0.433013) 
    MeshVertexNormal(0, 1, 0) 

    MeshVertexPosition(-0.816497, -0.333333, -0.471405)
    MeshVertexTextureCoordinate(0.750000, 0.433013) 
    MeshVertexNormal(0, 1, 0) 

    MeshVertexPosition(0.816497, -0.333333, -0.471405)
    MeshVertexTextureCoordinate(0.500000, 0.000000)
    MeshVertexNormal(0, 1, 0) 

    MeshFace(0,1,2)
    
    ; <<<<<<<<<<<<<<<<<<<<
    ; <<<<< 2nd face <<<<<
    
    MeshVertexPosition(0.000000,  1.000000,  0.000000) 
    MeshVertexTextureCoordinate(0.500000, 0.866026)
    MeshVertexNormal(0, 1, 0) 
    
    MeshVertexPosition(-0.816497, -0.333333, -0.471405)
    MeshVertexTextureCoordinate(0.750000, 0.433013)
    MeshVertexNormal(0, 1, 0) 
    
    MeshVertexPosition(0.000000, -0.333333,  0.942809)
    MeshVertexTextureCoordinate(0.250000, 0.433013)
    MeshVertexNormal(0, 1, 0) 
    
    MeshFace(3, 4, 5)
    
    ; <<<<<<<<<<<<<<<<<<<<
    ; <<<<< 3rd face <<<<<
    
    MeshVertexPosition(0.816497, -0.333333, -0.471405)
    MeshVertexTextureCoordinate(0.500000, 0.000000)
    MeshVertexNormal(0, 1, 0) 
    
    MeshVertexPosition(-0.816497, -0.333333, -0.471405)
    MeshVertexTextureCoordinate(0.750000, 0.433013)
    MeshVertexNormal(0, 1, 0) 
    
    MeshVertexPosition(0.000000,  1.000000,  0.000000)
    MeshVertexTextureCoordinate(1.000000, 0.000000)
    MeshVertexNormal(0, 1, 0) 
    
    MeshFace(6, 7, 8)
    
    ; <<<<<<<<<<<<<<<<<<<<
    ; <<<<< 4th face <<<<<
    
    MeshVertexPosition(0.000000,  1.000000,  0.000000)
    MeshVertexTextureCoordinate(0.000000, 0.000000)
    MeshVertexNormal(0, 1, 0) 
    
    MeshVertexPosition(0.000000, -0.333333,  0.942809)
    MeshVertexTextureCoordinate(0.250000, 0.433013)
    MeshVertexNormal(0, 1, 0) 
    
    MeshVertexPosition(0.816497, -0.333333, -0.471405)
    MeshVertexTextureCoordinate(0.500000, 0.000000)
    MeshVertexNormal(0, 1, 0) 
    
    MeshFace(9, 10, 11)
    
    FinishMesh(#True)
    TransformMesh(MeshID, 0, 0, 0, Size, Size, Size, 0, 0, 0, 0)
    
    NormalizeMesh(MeshID)

  EndIf
  
  ProcedureReturn MeshID
EndProcedure

#CameraSpeed = 2

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

Define.f KeyX, KeyY, MouseX, MouseY

If InitEngine3D()
	
	Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
	
	InitSprite()
	InitKeyboard()
	InitMouse()
	
	If Screen3DRequester()
		
		; Create a Tetrahedron
		CreateTetrahedron(0, 10.0)
		
		
		CreateMaterial(0, LoadTexture(0, "clouds.jpg"))
		SetMaterialColor(0, #PB_Material_AmbientColor, #PB_Material_AmbientColors)
		
		
		CreateEntity(0, MeshID(0), MaterialID(0))
		
		CreateCamera(0, 0, 0, 100, 100)
		MoveCamera(0, 0, 0, 100, #PB_Absolute)
		
		
		Repeat
			Screen3DEvents()
			
			If ExamineMouse()
				MouseX = MouseDeltaX() * #CameraSpeed * 0.05
				MouseY = MouseDeltaY() * #CameraSpeed * 0.05
			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
				
			EndIf
			
			RotateEntity(0, 0, 1, 0, #PB_Relative)
			
			RotateCamera(0, MouseY, MouseX, 0, #PB_Relative)
			MoveCamera  (0, KeyX, 0, KeyY)
			
			RenderWorld()
			Screen3DStats()      
			FlipBuffers()
		Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
	EndIf
	
Else
	MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf

End

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<
The Stone Age did not end due to a shortage of stones !
User avatar
StarBootics
Addict
Addict
Posts: 1006
Joined: Sun Jul 07, 2013 11:35 am
Location: Canada

Re: Cone, Torus & Pyramid

Post by StarBootics »

Hello everyone,

I'm still working on the cone mesh, I thought this will be easy but since I have created my cone with two different UV Mapping (Spherical and developed)
It's more complicated than I have anticipated because I have added a function to refit the UV mapping (scale and translate) to [0,1] range and this function need a 3X3 matrix and a vector3 libraries.
So the code for the cone mesh will be enormous...

So if some one have a working code, go for it.

Best regards
StarBootics
The Stone Age did not end due to a shortage of stones !
Post Reply