Geospheres - The better sphere

Blitz3D Forums/Blitz3D Programming/Geospheres - The better sphere

I have been working on getting a geosphere created in blitz.

A geosphere spreads it vertices evenly over the surface unlike the CreateSphere () command that tris get smaller the closer to the top/bottom.

I have got a geosphere of sorts going but I am have problems on how to texture it!

If any one has any ideas that would be great!

Has any one else worked on creating these?


GEOSPHERE (Work in Progress)
Graphics3D 800,600

SetBuffer BackBuffer()

Global title$="GeoSphere Test"
AppTitle title$
SetFont LoadFont("Arial",12)


Global gwm = GraphicsWidth()*.5,ghm = GraphicsHeight()*.5

Global you =   CreatePivot()
PositionEntity you,0,10,-90
Global         camrange = 2000
Global         cam=CreateCamera(you)
PositionEntity cam,0,0,0
CameraRange    cam,1,camrange
CameraClsColor cam,50,0,0

light=CreateLight()
PositionEntity light,200,200,200
LightRange light,10000

;Create Test Texture
skytex=CreateTexture(16,16,256)
SetBuffer TextureBuffer(skytex)
For count = 1 To 5
  Color 55*(count-1),10*count,255-55*(count-1)
  Rect count,count,15-count*2,15-count*2,1
Next
SetBuffer BackBuffer()
ScaleTexture skytex,.25,.25

Dim MidVert(2)
Dim TriVert(2)

base=createBox()
ScaleMesh base,50,50,50
EntityTexture base,skytex

MoveMouse gwm,ghm
MouseXSpeed
MouseYSpeed
start=MilliSecs()
showtext = 1
FPS = 50
period=1000/FPS
time=MilliSecs()-period

While Not KeyHit(1)

  now = MilliSecs() - start

  move(you)

  If MouseHit(1) Then
  ;Subdivide mesh to make geosphere
    level = level + 1
    base=chopmesh(base)
    EntityTexture base,skytex
    If ShowVertices Then ShowVert(base,2,.5,0)
  End If
  
  If MouseHit(2) Then
  ; show and number all Vertices for debuging
    If ShowVertices Then
      HideVert()
    Else
      ShowVert(base,2,.5,0)
    End If
    ShowVertices = Not ShowVertices
  End If

  If MouseHit(3) Then
    Wire = Not Wire
    WireFrame wire
  End If

  If KeyHit(57) Then
    showtext = Not showtext
  End If

  RenderWorld tween
  
  Color 125,125,120
  If ShowVertices Then
    VertsShown=DisplayVertNums()
    Text 650,580,"VertsShown = "+ VertsShown
  End If
    
  If showtext Then
    Color 25,125,250
    Text 10,580,"Level = "+ level +"   Triangles Rendered = "+TrisRendered()
    Text 10,10," Arrow Keys/Mouse to Move"
    Text 10,30," Left  Mouse Button to Subdivide and Spherize"
    Text 10,50," MIddle Mouse Button to Display in WireFrame Mode"
    Text 10,70," Right Mouse Button to Display and Number Vertices"
    Text 10,90," Space to Hide/Display this help"
  EndIf
  Flip

Wend
;--end of main loop



Global Speed#,SideSpeed#,EntPitch#,EntYaw#

Function Move(Ent)

  ;Rotation
  EntPitch# = MouseYSpeed()*.1  + EntPitch# * .95
  EntYaw#   = -MouseXSpeed()*.1 + EntYaw# * .95
  TurnEntity Ent,EntPitch#,EntYaw#,0
  
;  MoveMouse gwm,ghm
  
  ;Forward
  If  KeyDown(200) Then
    Thrust# = .1
  ElseIf KeyDown(208)Then ; Backwards
    Thrust# = -.1
  Else
    Thrust# =0
  End If

  ;Right
  If  KeyDown(205) Then
    SideThrust# = .1
  ElseIf KeyDown(203)Then ;Left
    SideThrust# = -.1
  Else
    SideThrust# =0
  End If
  
  Speed#     = Thrust# + (Speed# * .95)
  SideSpeed# = SideThrust# + (SideSpeed# * .95)

  MoveEntity Ent,SideSpeed#,0,Speed#
  
End Function


Function createBox(parent=0)

  Local mesh=CreateMesh(parent)
  Local surf=CreateSurface(mesh)
  
  ;front
  AddVertex surf,-.5,-.5, .5,  1,1;0
  AddVertex surf,-.5, .5, .5,  1,0;1
  AddVertex surf, .5, .5, .5,  0,0;2
  AddVertex surf, .5,-.5, .5,  0,1;3
  
  ;back
  AddVertex surf,-.5,-.5,-.5,  0,1;4
  AddVertex surf,-.5, .5,-.5,  0,0;5
  AddVertex surf, .5, .5,-.5,  1,0;6
  AddVertex surf, .5,-.5,-.5,  1,1;7
  
  ;front
  AddTriangle (surf,2,1,0)
  AddTriangle (surf,3,2,0)

  ;back
  AddTriangle (surf,4,5,7)
  AddTriangle (surf,5,6,7)
  
  ;lside
  AddTriangle (surf,0,1,5)
  AddTriangle (surf,4,0,5)

  ;rside
  AddTriangle (surf,2,3,6)
  AddTriangle (surf,3,7,6)

  ;top
  AddTriangle (surf,1,2,5)
  AddTriangle (surf,2,6,5)

  ;bottom
  AddTriangle (surf,0,4,7)
  AddTriangle (surf,3,0,7)

  UpdateNormals mesh
  Return mesh

End Function



Type vect
  Field vertA,vertB ,MidVert
  Field MidX#,MidY#,MidZ#
End Type


Function ChopMesh(oldmesh)
; create new mesh with each triangle subdivided into 4

  Local vc,nx#,ny#,nmz#,surf,trcount,tc,sc
  Local dx#,dy#,dz#
  mesh=CreateMesh()
  surfcount = CountSurfaces(oldmesh)
  
  For sc = 1 To surfcount
    surf=CreateSurface( mesh )

    oldsurf=GetSurface(oldmesh,sc)
    EntBrush=GetEntityBrush(Mesh)
    PaintEntity Mesh,EntBrush

    EntityFX mesh,18

    FindMeshCentre(oldMesh)

    dx#=VertexX(oldsurf,0)-MeshCentreX#
    dy#=VertexY(oldsurf,0)-MeshCentreY#
    dz#=VertexZ(oldsurf,0)-MeshCentreZ#
    Radius# = Sqr(dx#*dx#+dy#*dy#+dz#*dz#)
    ; Radius used to move vertices a equal distance from centre
    tricount = CountTriangles(oldsurf)
    Vertcount = CountVertices(oldsurf)

    Delete Each vect

    For vc = 0 To Vertcount -1
      AddVertex   surf,VertexX(oldsurf,vc),VertexY(oldsurf,vc),VertexZ(oldsurf,vc),VertexU(oldsurf,vc),VertexV(oldsurf,vc)
      VertexColor surf,vc,VertexRed(oldsurf,vc),VertexGreen(oldsurf,vc),VertexBlue(oldsurf,vc)
    Next
    For tc=  0 To tricount-1

      For vectcount = 0 To 2
        TriVert(vectcount)=TriangleVertex(oldsurf,tc,vectcount)
        If vectcount < 2 Then
          MidVert(vectcount)=HalfVect(oldsurf, TriVert(vectcount), TriangleVertex(oldsurf,tc,vectcount+1),surf,radius#)
        Else
          MidVert(vectcount)=HalfVect(oldsurf, TriangleVertex(oldsurf,tc,2), TriangleVertex(oldsurf,tc,0),surf,radius#)
        End If
  ;      debuglog  " tc= "+ tc + " vectcount = " +vectcount + " MidVert("+vectcount+") ="+ MidVert(vectcount)
      Next

      ; create new triangles
      AddTriangle surf,MidVert(0),MidVert(1),MidVert(2)
      AddTriangle surf,TriVert(0),MidVert(2),MidVert(0)
      AddTriangle surf,TriVert(1),MidVert(0),MidVert(1)
      AddTriangle surf,TriVert(2),MidVert(1),MidVert(2)

   If KeyHit(1) Then Exit
  ;    debuglog "MidVert(0)  = "+ MidVert(0)+" MidVert(1) = "+MidVert(1)+ " MidVert(2) = "+MidVert(2)
    Next

  ;--Redo texture coords

    For vc = 0 To CountVertices(surf) -1
      vx#=VertexX(surf,vc)
      vy#=VertexY(surf,vc)
      vz#=VertexZ(surf,vc)
      vpitch#=VectorPitch# ( vx#,vy#,vz# )
      vyaw#=VectorYaw# ( vx#,vy#,vz# )
;      if vyaw < 0 then vyaw = vyaw+360
;      if vpitch< 0 then vpitch = vpitch+360

      NewU# = ((vpitch+180)/360.0);+.5
      NewV# = ((vyaw+180)/360.0);+.5

      DebugLog vx+","+ vy+","+ vz+"  pitch = "+vpitch+ " yaw = "+vyaw+"  u= "+NewU#+"  v= "+NewV#
      VertexTexCoords surf,vc,NewU#,NewV#
    Next
  Next
    
  HideEntity oldmesh

;  spherize(mesh,radius#)


  UpdateNormals mesh
  Return mesh
End Function


Function HalfVect(surf,VertA,VertB,newsurf,radius#)
; Create or find existing vertex halfway between two existing vertices
; note: modified to move vertex to specified radius from centre
  Local VectExists
  Local dx#,dy#,dz#
  Local Dist#,DistDiff#

  VectExists = False
  ;look for existing
  For searchV.vect = Each vect
    If (searchV\vertA = VertA) And (searchV\vertB = VertB) Then VectExists = True :Exit
    If (searchV\vertA = VertB) And (searchV\vertB = VertA) Then VectExists = True :Exit
  Next

  If VectExists = False Then
    ; create new as no old one was found
    nv.vect = New vect
    nv\vertA = VertA
    nv\vertB = VertB
    nv\Midx#=VertexX(Surf,nv\vertA)+(VertexX(Surf,nv\vertB)-VertexX(Surf,nv\vertA))*.5
    nv\Midy#=VertexY(Surf,nv\vertA)+(VertexY(Surf,nv\vertB)-VertexY(Surf,nv\vertA))*.5
    nv\Midz#=VertexZ(Surf,nv\vertA)+(VertexZ(Surf,nv\vertB)-VertexZ(Surf,nv\vertA))*.5
    MidU#   =VertexU(Surf,nv\vertA)+(VertexU(Surf,nv\vertB)-VertexU(Surf,nv\vertA))*.5
    MidV#   =VertexV(Surf,nv\vertA)+(VertexV(Surf,nv\vertB)-VertexV(Surf,nv\vertA))*.5
    dx#=nv\Midx#-MeshCentreX#
    dy#=nv\Midy#-MeshCentreY#
    dz#=nv\Midz#-MeshCentreZ#
    Dist#=Sqr(dx#*dx#+dy#*dy#+dz#*dz#)
    DistDiff#=Radius#/Dist#
    nv\Midx#=(dx#*DistDiff#+MeshCentreX#)
    nv\Midy#=(dy#*DistDiff#+MeshCentreY#)
    nv\Midz#=(dz#*DistDiff#+MeshCentreZ#)
    nv\MidVert=AddVertex( newsurf, nv\Midx,nv\Midy,nv\Midz,MidU#,MidV#)
    Return nv\MidVert
  Else
    Return SearchV\Midvert
  End If
  DebugLog "Error: No Verts Found/Created for "+VertA+" and "+VertB +" they are not in same triangle"
  Return -1
  
End Function




Global MeshCentreX#,MeshCentreY#,MeshCentreZ#

Function FindMeshCentre(Mesh)
  Local vcount,totX#,totY#,totZ#
  Local surf,surfcount = CountSurfaces(Mesh)
  Local VertTot
  If surfcount > 0 Then
    For scount = 1 To  surfcount
      surf=GetSurface(Mesh,scount)
      Vertcount = CountVertices(surf)
      VertTot =  VertTot + Vertcount
      For vcount = 0 To Vertcount-1
        totX# = totX# + VertexX(surf,vcount)
        totY# = totY# + VertexY(surf,vcount)
        totZ# = totZ# + VertexZ(surf,vcount)
      Next
    Next
  End If

  MeshCentreX# = totX# / VertTot
  MeshCentreY# = totY# / VertTot
  MeshCentreZ# = totZ# / VertTot

End Function


;---Debug Functions
Type vp
Field ent,num
End Type

Function ShowVert(mesh,ssize=3,size#=.1,UseVertCol=False)

  Delete Each vp
  For sc = 1 To CountSurfaces(mesh)
    surf=GetSurface(mesh,sc)
    maxvert=CountVertices(surf)

    For vc = 0 To maxvert-1
  	   dot.vp= New vp
  	   dot\num = vc
      dot\ent = CreateSphere(ssize,mesh);
      PositionEntity dot\ent,VertexX(surf,vc),VertexY(surf,vc),VertexZ(surf,vc)
      vr=VertexRed(surf,vc)
      vg=VertexGreen(surf,vc)
      vb=VertexBlue(surf,vc)
      c=EntityDistance(dot\ent,mesh)*100 Mod 255
	  	  If UseVertCol Then
	  	    EntityColor dot\ent,vr,vg,vb
      Else
			     EntityColor dot\ent,c,Sin(vc)*255,255-c
     End If
     ScaleEntity dot\ent,size,size,size
     If KeyHit(1) Then End
    Next
  Next

End Function

Function HideVert()
  For tvp.vp = Each vp
    HideEntity tvp\ent
  Next
  Delete Each vp

End Function


Function DisplayVertNums()

  Local vertc = 0
  Color 200,200,200
  For dot.vp = Each vp

    If EntityInView(dot\ent,cam) Then
      CameraProject(cam,EntityX(dot\ent),EntityY(dot\ent),EntityZ(dot\ent))
      Text ProjectedX#(),ProjectedY#(),dot\num
       vertc =  vertc +1
    End If
  Next

  Return vertc
End Function


End


I didn't do this myself yet, but I think I would first try to UV-map it by using the 3D coords of the vertices, shifted to values between 0 an 1.0. Since you can set UVW, this should be easy. At least if Blitz really utilizes UVW and doesn't ignore W - which I am not sure right now.

you can just download wings3d and use the create geosphere option,
The problem with geospheres is that they dont unwrap to a square shape unlike spheres.

If you subdivide an icosahedron, your verts are always evenly spaced, and the sphere breaks down naturally into 2 poles and an equatorial strip.

Here is a quickie I did to gen an icosahedron and subdivide it

cursor to move around... "S" to subdivide the mesh

The code generates a mesh with 3 surfaces.. north pole, south pole, and equator... should be easy enuf to texture :)


; Setup the screen dimensions
Global ScreenWidth  = 640
Global ScreenHeight = 480
Global ScreenDepth  = 16
Global ScreenMode   = 2

; Create the screen.
Graphics3D ScreenWidth,ScreenHeight,ScreenDepth,ScreenMode 
SetBuffer BackBuffer()     ; Switch to Back Buffer for Double Buffered drawing.

; Setup the lighting...
AmbientLight 100,100,100

; CAMERA PIVOT
Global camera_pivot= CreatePivot()
EntityRadius camera_pivot,0.1

; Setup the camera.
Global camera = CreateCamera(camera_pivot)
CameraRange camera,1,10
CameraViewport camera,0,0,ScreenWidth,ScreenHeight
CameraProjMode camera,2

mesh = CreateMesh()
top = CreateSurface(mesh)
mdl = CreateSurface(mesh)
bot = CreateSurface(mesh)

brush = CreateBrush(255,255,255)
PaintSurface(top, brush)
PaintSurface(mdl, brush)
PaintSurface(bot, brush)

PositionEntity(camera_pivot, 0, 0, 0)
PositionEntity(camera, 0, 0, -8)

ScaleEntity(mesh, 0.5, 0.5, 0.5);

AddVertex(top, 0, 1, 0)
For i=0 To 4
	x# = Sin#(72*i)
	y# = Sin#(30)
	z# = Cos#(72*i)
	DebugLog "vert x="+x#+" y="+y#+" z="+z#
	AddVertex(top, x#, y#, z#)
Next
For i=1 To 4
	AddTriangle(top, 0, i+1, i)
Next
AddTriangle(top, 0, 1, 5)


AddVertex(bot, 0, -1, 0)
For i=0 To 4
	x# = Sin#(72*(i+0.5))
	y# = -Sin#(30)
	z# = Cos#(72*(i+0.5))
	DebugLog "vert x="+x#+" y="+y#+" z="+z#
	AddVertex(bot, x#, y#, z#)
Next
For i=1 To 4
	AddTriangle(bot, i, i+1, 0)
Next
AddTriangle(bot, 5, 1, 0)


For i=1 To 5
	AddVertex(mdl, VertexX(top,i), VertexY(top,i), VertexZ(top,i))
	AddVertex(mdl, VertexX(bot,i), VertexY(bot,i), VertexZ(bot,i))
Next
For i=0 To 6 Step 2
	AddTriangle(mdl, i, i+2, i+1)
	AddTriangle(mdl, i+1, i+2, i+3)
Next
AddTriangle(mdl, 8, 0, 9)
AddTriangle(mdl, 9, 0, 1)
	

UpdateNormals(mesh)

WireFrame True

Repeat
	If KeyDown(31)
		While Not KeyDown(31)
		Wend
		mesh = subdiv(mesh)
	EndIf

	If KeyDown(200) TurnEntity(camera_pivot, 1, 0, 0)
	If KeyDown(208) TurnEntity(camera_pivot, -1, 0, 0)
	If KeyDown(203) TurnEntity(camera_pivot, 0, +1, 0)
	If KeyDown(205) TurnEntity(camera_pivot, 0, -1, 0)
	RenderWorld
	
	Flip
	
Until KeyDown(1)

Global newmesh
Global newsurf

Type subdivvect
	Field x#
	Field y#
	Field z#
End Type

Function subdiv(mesh)
	newmesh = CreateMesh()
	For i=1 To CountSurfaces(mesh)
		subdivsurf(GetSurface(mesh,i))
	Next
	FreeEntity mesh
	Return newmesh
End Function

Function subdivsurf(surf)
	newsurf = CreateSurface(newmesh)
	tris = CountTriangles(surf)-1
	For i=0 To tris
		c1.subdivvect = spherize(GetCoords(surf,TriangleVertex(surf,i,0)))
		c2.subdivvect = spherize(GetCoords(surf,TriangleVertex(surf,i,1)))
		c3.subdivvect = spherize(GetCoords(surf,TriangleVertex(surf,i,2)))
		c4.subdivvect = spheresplit(c1,c2)
		c5.subdivvect = spheresplit(c2,c3)
		c6.subdivvect = spheresplit(c3,c1)
		Vects2Triangle(c1,c4,c6)
		Vects2Triangle(c4,c2,c5)
		Vects2Triangle(c5,c3,c6)
		Vects2Triangle(c4,c5,c6)
	Next
End Function

Function spheresplit.subdivvect(c1.subdivvect, c2.subdivvect)
	res.subdivvect = New subdivvect
	res\x# = (c1\x# + c2\x#)/2
	res\y# = (c1\y# + c2\y#)/2
	res\z# = (c1\z# + c2\z#)/2
	res = spherize(res)
	Return res
End Function

Function spherize.subdivvect(c.subdivvect)
	res.subdivvect = New subdivvect
	d# = 1/Sqr(c\x#*c\x# + c\y#*c\y# + c\z#*c\z#)
	res\x# = c\x# * d#
	res\y# = c\y# * d#
	res\z# = c\z# * d#
	Return res
End Function

Function GetCoords.subdivvect(surf, vert)
	res.subdivvect = New subdivvect
	res\x = VertexX(surf,vert)
 	res\y = VertexY(surf,vert)
	res\z = VertexZ(surf,vert)
	Return res
End Function

Function Vects2Triangle(c1.subdivvect,c2.subdivvect,c3.subdivvect)
	v1 = vertindex(newsurf, c1)
	v2 = vertindex(newsurf, c2)
	v3 = vertindex(newsurf, c3)
	AddTriangle(newsurf, v1, v2, v3)
End Function

Function vertindex(surf, c.subdivvect)
	verts = CountVertices(surf) - 1
	For i=0 To verts
		If VertexX(surf,i)=c\x And VertexY(surf,i)=c\y And VertexZ(surf,i)=c\z
			Return i
		EndIf
	Next
	Return AddVertex(surf, c\x, c\y, c\z)
End Function


Thanks ZombieWoof that code looks like it may do the trick.

Using a icosahedron creates a much better layout of the final triangles.

I had to run that code just to find out what an icosahedron is! :P

the initial coords of the icosahedron are wrong -- someone want to fix up the math ??

use spherical mapping: http://membres.lycos.fr/amycoders/tutorials/tm_approx.html

Use an icosahedron

and try wilbur:
http://www.ridgenet.net/~jslayton/software.html

can someone do a tutorial for newbies in the tutorial section??
PLEASE!

ZombieWoof :
Have you been here ?
http://astronomy.swin.edu.au/~pbourke/polyhedra/platonic/

I used a tetrahedron then a cube as it was easier as a starting point to get by brain around the problem. Getting it working with a Icosahedron would be perfect.

Dirk:
Wilber looks like a great prog for creating maping textures. Have to see what it can do.

Nope -- didnt find that one -- but its got the math I need -- will give it a shot and update the code if it works

Corrected icosahedron code


; Setup the screen dimensions
Global ScreenWidth  = 640
Global ScreenHeight = 480
Global ScreenDepth  = 16
Global ScreenMode   = 2

; Create the screen.
Graphics3D ScreenWidth,ScreenHeight,ScreenDepth,ScreenMode 
SetBuffer BackBuffer()     ; Switch to Back Buffer for Double Buffered drawing.

; Setup the lighting...
AmbientLight 100,100,100

; CAMERA PIVOT
Global camera_pivot= CreatePivot()
EntityRadius camera_pivot,0.1

; Setup the camera.
Global camera = CreateCamera(camera_pivot)
CameraRange camera,1,10
CameraViewport camera,0,0,ScreenWidth,ScreenHeight
CameraProjMode camera,2

PositionEntity(camera_pivot, 0, 0, 0)
PositionEntity(camera, 0, 0, -8)

mesh = CreateMesh()
top = CreateSurface(mesh)
mdl = CreateSurface(mesh)
bot = CreateSurface(mesh)

brush = CreateBrush(255,255,255)
PaintSurface(top, brush)
PaintSurface(mdl, brush)
PaintSurface(bot, brush)

;ScaleEntity(mesh, 0.3, 0.3, 0.3);

a# = 0.5
b# = 1.0 / (1.0 + Sqr(5.0)) 

;01 0  b -a    b  a  0   -b  a  0
v1 = vertndx(mdl, 0,b,-a)
v2 = vertndx(mdl, b,a,0)
v3 = vertndx(mdl, -b,a,0)
AddTriangle(mdl,v1,v2,v3)
;02 0  b  a   -b  a  0    b  a  0
v1 = vertndx(mdl, 0,b,a)
v2 = vertndx(mdl, -b,a,0)
v3 = vertndx(mdl, b,a,0)
AddTriangle(mdl,v1,v2,v3)
;03 0  b  a    0 -b  a   -a  0  b
v1 = vertndx(mdl, 0,b,a)
v2 = vertndx(mdl, 0,-b,a)
v3 = vertndx(mdl, -a,0,b)
AddTriangle(mdl,v1,v2,v3)
;04 0  b  a    a  0  b    0 -b  a
v1 = vertndx(mdl, 0,b,a)
v2 = vertndx(mdl, a,0,b)
v3 = vertndx(mdl, 0,-b,a)
AddTriangle(mdl,v1,v2,v3)
;05 0  b -a    0 -b -a    a  0 -b
v1 = vertndx(mdl, 0,b,-a)
v2 = vertndx(mdl, 0,-b,-a)
v3 = vertndx(mdl, a,0,-b)
AddTriangle(mdl,v1,v2,v3)
;06 0  b -a   -a  0 -b    0 -b -a
v1 = vertndx(mdl, 0,b,-a)
v2 = vertndx(mdl, -a,0,-b)
v3 = vertndx(mdl, 0,-b,-a)
AddTriangle(mdl,v1,v2,v3)
;07 0 -b  a    b -a  0   -b -a  0
v1 = vertndx(mdl, 0,-b,a)
v2 = vertndx(mdl, b,-a,0)
v3 = vertndx(mdl, -b,-a,0)
AddTriangle(mdl,v1,v2,v3)
;08 0 -b -a   -b -a  0    b -a  0
v1 = vertndx(mdl, 0,-b,-a)
v2 = vertndx(mdl, -b,-a,0)
v3 = vertndx(mdl, b,-a,0)
AddTriangle(mdl,v1,v2,v3)
;09 -b a  0   -a  0  b   -a  0 -b
v1 = vertndx(mdl, -b,a,0)
v2 = vertndx(mdl, -a,0,b)
v3 = vertndx(mdl, -a,0,-b)
AddTriangle(mdl,v1,v2,v3)
;10 -b-a  0   -a  0 -b   -a  0  b
v1 = vertndx(mdl, -b,-a,0)
v2 = vertndx(mdl, -a,0,-b)
v3 = vertndx(mdl, -a,0,b)
AddTriangle(mdl,v1,v2,v3)
;11 b  a  0    a  0 -b    a  0  b
v1 = vertndx(mdl, b,a,0)
v2 = vertndx(mdl, a,0,-b)
v3 = vertndx(mdl, a,0,b)
AddTriangle(mdl,v1,v2,v3)
;12 b -a  0    a  0  b    a  0 -b
v1 = vertndx(mdl, b,-a,0)
v2 = vertndx(mdl, a,0,b)
v3 = vertndx(mdl, a,0,-b)
AddTriangle(mdl,v1,v2,v3)
;13 0  b  a   -a  0  b   -b  a  0
v1 = vertndx(mdl, 0,b,a)
v2 = vertndx(mdl, -a,0,b)
v3 = vertndx(mdl, -b,a,0)
AddTriangle(mdl,v1,v2,v3)
;14 0  b  a    b  a  0    a  0  b
v1 = vertndx(mdl, 0,b,a)
v2 = vertndx(mdl, b,a,0)
v3 = vertndx(mdl, a,0,b)
AddTriangle(mdl,v1,v2,v3)
;15 0  b -a   -b  a  0   -a  0 -b
v1 = vertndx(mdl, 0,b,-a)
v2 = vertndx(mdl, -b,a,0)
v3 = vertndx(mdl, -a,0,-b)
AddTriangle(mdl,v1,v2,v3)
;16 0  b -a    a  0 -b    b  a  0
v1 = vertndx(mdl, 0,b,-a)
v2 = vertndx(mdl, a,0,-b)
v3 = vertndx(mdl, b,a,0)
AddTriangle(mdl,v1,v2,v3)
;17 0 -b -a   -a  0 -b   -b -a  0
v1 = vertndx(mdl, 0,-b,-a)
v2 = vertndx(mdl, -a,0,-b)
v3 = vertndx(mdl, -b,-a,0)
AddTriangle(mdl,v1,v2,v3)
;18 0 -b -a    b -a  0    a  0 -b
v1 = vertndx(mdl, 0,-b,-a)
v2 = vertndx(mdl, b,-a,0)
v3 = vertndx(mdl, a,0,-b)
AddTriangle(mdl,v1,v2,v3)
;19 0 -b  a   -b -a  0   -a  0  b
v1 = vertndx(mdl, 0,-b,a)
v2 = vertndx(mdl, -b,-a,0)
v3 = vertndx(mdl, -a,0,b)
AddTriangle(mdl,v1,v2,v3)
;20 0 -b  a    a  0  b    b -a  0
v1 = vertndx(mdl, 0,-b,a)
v2 = vertndx(mdl, a,0,b)
v3 = vertndx(mdl, b,-a,0)
AddTriangle(mdl,v1,v2,v3)


;AddVertex(top, 0, 1, 0)
;For i=0 To 4
;	x# = Sin#(72*i) * Sin(60)
;	y# = Cos#(60)
;	z# = Cos#(72*i) * Sin(60)
;	DebugLog "vert x="+x#+" y="+y#+" z="+z#
;	AddVertex(top, x#, y#, z#)
;Next
;For i=1 To 4
;	AddTriangle(top, 0, i+1, i)
;Next
;AddTriangle(top, 0, 1, 5)
;
;
;AddVertex(bot, 0, -1, 0)
;For i=0 To 4
;	j # = i + 0.5
;	x# = Sin#(72*j#) * Sin(60)
;	y# = -Cos#(60)
;	z# = Cos#(72*j#) * Sin(60)
;	DebugLog "vert x="+x#+" y="+y#+" z="+z#
;	AddVertex(bot, x#, y#, z#)
;Next
;For i=1 To 4
;	AddTriangle(bot, i, i+1, 0)
;Next
;AddTriangle(bot, 5, 1, 0)

;For i=1 To 5
;	AddVertex(mdl, VertexX(top,i), VertexY(top,i), VertexZ(top,i))
;	AddVertex(mdl, VertexX(bot,i), VertexY(bot,i), VertexZ(bot,i))
;Next
;For i=0 To 6 Step 2
;	AddTriangle(mdl, i, i+2, i+1)
;	AddTriangle(mdl, i+1, i+2, i+3)
;Next
;AddTriangle(mdl, 8, 0, 9)
;AddTriangle(mdl, 9, 0, 1)
	

UpdateNormals(mesh)

WireFrame True

Repeat
	If KeyDown(31)
		While Not KeyDown(31)
		Wend
		mesh = subdiv(mesh)
	EndIf

	If KeyDown(200) TurnEntity(camera_pivot, 1, 0, 0)
	If KeyDown(208) TurnEntity(camera_pivot, -1, 0, 0)
	If KeyDown(203) TurnEntity(camera_pivot, 0, +1, 0)
	If KeyDown(205) TurnEntity(camera_pivot, 0, -1, 0)
	RenderWorld
	
	Flip
	
Until KeyDown(1)

Global newmesh
Global newsurf

Type subdivvect
	Field x#
	Field y#
	Field z#
End Type

Function subdiv(mesh)
	newmesh = CreateMesh()
	For i=1 To CountSurfaces(mesh)
		subdivsurf(GetSurface(mesh,i))
	Next
	FreeEntity mesh
	Return newmesh
End Function

Function subdivsurf(surf)
	newsurf = CreateSurface(newmesh)
	tris = CountTriangles(surf)-1
	For i=0 To tris
		c1.subdivvect = spherize(GetCoords(surf,TriangleVertex(surf,i,0)))
		c2.subdivvect = spherize(GetCoords(surf,TriangleVertex(surf,i,1)))
		c3.subdivvect = spherize(GetCoords(surf,TriangleVertex(surf,i,2)))
		c4.subdivvect = spheresplit(c1,c2)
		c5.subdivvect = spheresplit(c2,c3)
		c6.subdivvect = spheresplit(c3,c1)
		Vects2Triangle(c1,c4,c6)
		Vects2Triangle(c4,c2,c5)
		Vects2Triangle(c5,c3,c6)
		Vects2Triangle(c4,c5,c6)
	Next
End Function

Function spheresplit.subdivvect(c1.subdivvect, c2.subdivvect)
	res.subdivvect = New subdivvect
	res\x# = (c1\x# + c2\x#)/2.0
	res\y# = (c1\y# + c2\y#)/2.0
	res\z# = (c1\z# + c2\z#)/2.0
	res = spherize(res)
	Return res
End Function

Function spherize.subdivvect(c.subdivvect)
	res.subdivvect = New subdivvect
	d# = 1.0/Sqr(c\x#*c\x# + c\y#*c\y# + c\z#*c\z#)
	res\x# = c\x# * d#
	res\y# = c\y# * d#
	res\z# = c\z# * d#
	Return res
End Function

Function GetCoords.subdivvect(surf, vert)
	res.subdivvect = New subdivvect
	res\x# = VertexX#(surf,vert)
 	res\y# = VertexY#(surf,vert)
	res\z# = VertexZ#(surf,vert)
	Return res
End Function

Function Vects2Triangle(c1.subdivvect,c2.subdivvect,c3.subdivvect)
	v1 = vertindex(newsurf, c1)
	v2 = vertindex(newsurf, c2)
	v3 = vertindex(newsurf, c3)
	AddTriangle(newsurf, v1, v2, v3)
End Function

Function vertindex(surf, c.subdivvect)
	verts = CountVertices(surf) - 1
	For i=0 To verts
		If VertexX#(surf,i)=c\x# And VertexY#(surf,i)=c\y# And VertexZ#(surf,i)=c\z#
			Return i
		EndIf
	Next
	Return AddVertex(surf, c\x#, c\y#, c\z#)
End Function

Function vertndx(surf, x#,y#,z#)
	verts = CountVertices(surf) - 1
	For i=0 To verts
		If VertexX#(surf,i)=x# And VertexY#(surf,i)=y# And VertexZ#(surf,i)=z#
			Return i
		EndIf
	Next
	Return AddVertex(surf, x#, y#, z#)
End Function


btw == how do folks to the code in the scrollable textarea ??

That looks amazing.

Now to get a textures uv's working and that would be the best sphere creating I have seen in Blitz!

I do not understand what
"btw == how do folks to the code in the scrollable textarea ?? " means . Sorry!

Slenkar: What kind of Tute do you mean?


btw == how do folks to the code in the scrollable textarea ??


use <codebox></codebox>

You know this code:
		While Not KeyDown(31)
		Wend
should be:
		While KeyDown(31)
		Wend

Surprised no one has noticed it.

I had changed it a keyhit(31) but forgot to mention it!

@master: thanks for the bugfix :)

@zitch: since the new code messed up my poles+equator setup, I've gotta go figure which triangle is which and reassign the them to the right surfaces... then it'll be a lot easier for me to setup the u/v

New version with surfaces fixed, colorized:


; Setup the screen dimensions
Global ScreenWidth  = 640
Global ScreenHeight = 480
Global ScreenDepth  = 16
Global ScreenMode   = 2

; Create the screen.
Graphics3D ScreenWidth,ScreenHeight,ScreenDepth,ScreenMode 
SetBuffer BackBuffer()     ; Switch to Back Buffer for Double Buffered drawing.

; Setup the lighting...
AmbientLight 100,100,100

; CAMERA PIVOT
Global camera_pivot= CreatePivot()
EntityRadius camera_pivot,0.1

; Setup the camera.
Global camera = CreateCamera(camera_pivot)
CameraRange camera,1,10
CameraViewport camera,0,0,ScreenWidth,ScreenHeight
CameraProjMode camera,2

PositionEntity(camera_pivot, 0, 0, 0)
PositionEntity(camera, 0, 0, -8)

mesh = CreateMesh()
top = CreateSurface(mesh)
mdl = CreateSurface(mesh)
bot = CreateSurface(mesh)

rbrush = CreateBrush(255,0,0)
gbrush = CreateBrush(0,255,0)
bbrush = CreateBrush(0,0,255)
PaintSurface(top, rbrush)
PaintSurface(mdl, gbrush)
PaintSurface(bot, bbrush)

;ScaleEntity(mesh, 0.3, 0.3, 0.3);

a# = 0.5
b# = 1.0 / (1.0 + Sqr(5.0)) 

;01 0  b -a    b  a  0   -b  a  0
surf=mdl
v1 = vertndx(surf, 0,b,-a)
v2 = vertndx(surf, b,a,0)
v3 = vertndx(surf, -b,a,0)
AddTriangle(surf,v1,v2,v3)
;02 0  b  a   -b  a  0    b  a  0
surf=mdl
v1 = vertndx(surf, 0,b,a)
v2 = vertndx(surf, -b,a,0)
v3 = vertndx(surf, b,a,0)
AddTriangle(surf,v1,v2,v3)
;03 0  b  a    0 -b  a   -a  0  b
surf=mdl
v1 = vertndx(surf, 0,b,a)
v2 = vertndx(surf, 0,-b,a)
v3 = vertndx(surf, -a,0,b)
AddTriangle(surf,v1,v2,v3)
;04 0  b  a    a  0  b    0 -b  a
surf=top
v1 = vertndx(surf, 0,b,a)
v2 = vertndx(surf, a,0,b)
v3 = vertndx(surf, 0,-b,a)
AddTriangle(surf,v1,v2,v3)
;05 0  b -a    0 -b -a    a  0 -b
surf=mdl
v1 = vertndx(surf, 0,b,-a)
v2 = vertndx(surf, 0,-b,-a)
v3 = vertndx(surf, a,0,-b)
AddTriangle(surf,v1,v2,v3)
;06 0  b -a   -a  0 -b    0 -b -a
surf=bot
v1 = vertndx(surf, 0,b,-a)
v2 = vertndx(surf, -a,0,-b)
v3 = vertndx(surf, 0,-b,-a)
AddTriangle(surf,v1,v2,v3)
;07 0 -b  a    b -a  0   -b -a  0
surf=mdl
v1 = vertndx(surf, 0,-b,a)
v2 = vertndx(surf, b,-a,0)
v3 = vertndx(surf, -b,-a,0)
AddTriangle(surf,v1,v2,v3)
;08 0 -b -a   -b -a  0    b -a  0
surf=mdl
v1 = vertndx(surf, 0,-b,-a)
v2 = vertndx(surf, -b,-a,0)
v3 = vertndx(surf, b,-a,0)
AddTriangle(surf,v1,v2,v3)
;09 -b a  0   -a  0  b   -a  0 -b
surf=bot
v1 = vertndx(surf, -b,a,0)
v2 = vertndx(surf, -a,0,b)
v3 = vertndx(surf, -a,0,-b)
AddTriangle(surf,v1,v2,v3)
;10 -b-a  0   -a  0 -b   -a  0  b
surf=bot
v1 = vertndx(surf, -b,-a,0)
v2 = vertndx(surf, -a,0,-b)
v3 = vertndx(surf, -a,0,b)
AddTriangle(surf,v1,v2,v3)
;11 b  a  0    a  0 -b    a  0  b
surf=top
v1 = vertndx(surf, b,a,0)
v2 = vertndx(surf, a,0,-b)
v3 = vertndx(surf, a,0,b)
AddTriangle(surf,v1,v2,v3)
;12 b -a  0    a  0  b    a  0 -b
surf=top
v1 = vertndx(surf, b,-a,0)
v2 = vertndx(surf, a,0,b)
v3 = vertndx(surf, a,0,-b)
AddTriangle(surf,v1,v2,v3)
;13 0  b  a   -a  0  b   -b  a  0
surf=mdl
v1 = vertndx(surf, 0,b,a)
v2 = vertndx(surf, -a,0,b)
v3 = vertndx(surf, -b,a,0)
AddTriangle(surf,v1,v2,v3)
;14 0  b  a    b  a  0    a  0  b
surf=top
v1 = vertndx(surf, 0,b,a)
v2 = vertndx(surf, b,a,0)
v3 = vertndx(surf, a,0,b)
AddTriangle(surf,v1,v2,v3)
;15 0  b -a   -b  a  0   -a  0 -b
surf=bot
v1 = vertndx(surf, 0,b,-a)
v2 = vertndx(surf, -b,a,0)
v3 = vertndx(surf, -a,0,-b)
AddTriangle(surf,v1,v2,v3)
;16 0  b -a    a  0 -b    b  a  0
surf=mdl
v1 = vertndx(surf, 0,b,-a)
v2 = vertndx(surf, a,0,-b)
v3 = vertndx(surf, b,a,0)
AddTriangle(surf,v1,v2,v3)
;17 0 -b -a   -a  0 -b   -b -a  0
surf=bot
v1 = vertndx(surf, 0,-b,-a)
v2 = vertndx(surf, -a,0,-b)
v3 = vertndx(surf, -b,-a,0)
AddTriangle(surf,v1,v2,v3)
;18 0 -b -a    b -a  0    a  0 -b
surf=mdl
v1 = vertndx(surf, 0,-b,-a)
v2 = vertndx(surf, b,-a,0)
v3 = vertndx(surf, a,0,-b)
AddTriangle(surf,v1,v2,v3)
;19 0 -b  a   -b -a  0   -a  0  b
surf=mdl
v1 = vertndx(surf, 0,-b,a)
v2 = vertndx(surf, -b,-a,0)
v3 = vertndx(surf, -a,0,b)
AddTriangle(surf,v1,v2,v3)
;20 0 -b  a    a  0  b    b -a  0
surf=top
v1 = vertndx(surf, 0,-b,a)
v2 = vertndx(surf, a,0,b)
v3 = vertndx(surf, b,-a,0)
AddTriangle(surf,v1,v2,v3)


;AddVertex(surf, 0, 1, 0)
;For i=0 To 4
;	x# = Sin#(72*i) * Sin(60)
;	y# = Cos#(60)
;	z# = Cos#(72*i) * Sin(60)
;	DebugLog "vert x="+x#+" y="+y#+" z="+z#
;	AddVertex(surf, x#, y#, z#)
;Next
;For i=1 To 4
;	AddTriangle(surf, 0, i+1, i)
;Next
;AddTriangle(surf, 0, 1, 5)
;
;
;AddVertex(surf, 0, -1, 0)
;For i=0 To 4
;	j # = i + 0.5
;	x# = Sin#(72*j#) * Sin(60)
;	y# = -Cos#(60)
;	z# = Cos#(72*j#) * Sin(60)
;	DebugLog "vert x="+x#+" y="+y#+" z="+z#
;	AddVertex(surf, x#, y#, z#)
;Next
;For i=1 To 4
;	AddTriangle(surf, i, i+1, 0)
;Next
;AddTriangle(surf, 5, 1, 0)

;For i=1 To 5
;	AddVertex(surf, VertexX(surf,i), VertexY(surf,i), VertexZ(surf,i))
;	AddVertex(surf, VertexX(surf,i), VertexY(surf,i), VertexZ(surf,i))
;Next
;For i=0 To 6 Step 2
;	AddTriangle(surf, i, i+2, i+1)
;	AddTriangle(surf, i+1, i+2, i+3)
;Next
;AddTriangle(surf, 8, 0, 9)
;AddTriangle(surf, 9, 0, 1)
	

UpdateNormals(mesh)

WireFrame True

Repeat
	If KeyDown(31)
		While KeyDown(31)
		Wend
		mesh = subdiv(mesh)
		PaintSurface(GetSurface(mesh,1), rbrush)
		PaintSurface(GetSurface(mesh,2), gbrush)
		PaintSurface(GetSurface(mesh,3), bbrush)
	EndIf

	If KeyDown(200) TurnEntity(camera_pivot, 1, 0, 0)
	If KeyDown(208) TurnEntity(camera_pivot, -1, 0, 0)
	If KeyDown(203) TurnEntity(camera_pivot, 0, +1, 0)
	If KeyDown(205) TurnEntity(camera_pivot, 0, -1, 0)
	RenderWorld
	
	Flip
	
Until KeyDown(1)

Global newmesh
Global newsurf

Type subdivvect
	Field x#
	Field y#
	Field z#
End Type

Function subdiv(mesh)
	newmesh = CreateMesh()
	For i=1 To CountSurfaces(mesh)
		subdivsurf(GetSurface(mesh,i))
	Next
	FreeEntity mesh
	Return newmesh
End Function

Function subdivsurf(surf)
	newsurf = CreateSurface(newmesh)
	tris = CountTriangles(surf)-1
	For i=0 To tris
		c1.subdivvect = spherize(GetCoords(surf,TriangleVertex(surf,i,0)))
		c2.subdivvect = spherize(GetCoords(surf,TriangleVertex(surf,i,1)))
		c3.subdivvect = spherize(GetCoords(surf,TriangleVertex(surf,i,2)))
		c4.subdivvect = spheresplit(c1,c2)
		c5.subdivvect = spheresplit(c2,c3)
		c6.subdivvect = spheresplit(c3,c1)
		Vects2Triangle(c1,c4,c6)
		Vects2Triangle(c4,c2,c5)
		Vects2Triangle(c5,c3,c6)
		Vects2Triangle(c4,c5,c6)
	Next
End Function

Function spheresplit.subdivvect(c1.subdivvect, c2.subdivvect)
	res.subdivvect = New subdivvect
	res\x# = (c1\x# + c2\x#)/2.0
	res\y# = (c1\y# + c2\y#)/2.0
	res\z# = (c1\z# + c2\z#)/2.0
	res = spherize(res)
	Return res
End Function

Function spherize.subdivvect(c.subdivvect)
	res.subdivvect = New subdivvect
	d# = 1.0/Sqr(c\x#*c\x# + c\y#*c\y# + c\z#*c\z#)
	res\x# = c\x# * d#
	res\y# = c\y# * d#
	res\z# = c\z# * d#
	Return res
End Function

Function GetCoords.subdivvect(surf, vert)
	res.subdivvect = New subdivvect
	res\x# = VertexX#(surf,vert)
 	res\y# = VertexY#(surf,vert)
	res\z# = VertexZ#(surf,vert)
	Return res
End Function

Function Vects2Triangle(c1.subdivvect,c2.subdivvect,c3.subdivvect)
	v1 = vertindex(newsurf, c1)
	v2 = vertindex(newsurf, c2)
	v3 = vertindex(newsurf, c3)
	AddTriangle(newsurf, v1, v2, v3)
End Function

Function vertindex(surf, c.subdivvect)
	verts = CountVertices(surf) - 1
	For i=0 To verts
		If VertexX#(surf,i)=c\x# And VertexY#(surf,i)=c\y# And VertexZ#(surf,i)=c\z#
			Return i
		EndIf
	Next
	Return AddVertex(surf, c\x#, c\y#, c\z#)
End Function

Function vertndx(surf, x#,y#,z#)
	verts = CountVertices(surf) - 1
	For i=0 To verts
		If VertexX#(surf,i)=x# And VertexY#(surf,i)=y# And VertexZ#(surf,i)=z#
			Return i
		EndIf
	Next
	Return AddVertex(surf, x#, y#, z#)
End Function


having a problem getting ultimate unwrap to deal with the mesh... apparently the b3d writer in makeb3d is a little broken

hehehe ultimate unwrap does geospheres using icosahedrons, plus exports b3d :)

here is the map I finally came up with

couldnt get it to do the equator the way I wanted.. might have to gen my own u/v to get what I want



the community needs a tutorial on the easiest way to get a single image onto a geo-sphere in either blitz or ultimate unwrap.-seamless of course

ZombieWoof:

Did you figure out the UV's ?

Nope -- I cheated and grabbed a copy of Ultimate Unwrap after adding code to save the mesh to B3D :) Was kinda busy getting the alpha release of Game Manager ready to post.

And now of course I'm off on other things :)

There are some recent posts on uv mapping if you want to take a shot at having the code generate the UV data... and we've suggested a couple of different mappings in this thread.

I ended up finding an example in on how to convert a texture to a spherical map.

With this function you can then use a CreateSphere then texture it with the new texture and it look great!

I got the code from Paul Bourke's cool site
http://astronomy.swin.edu.au/~pbourke/texture/polargrid/

I will post when it is working.

Thanks all for the input

Spheres suck. Why couldn't the world have been a torus?

that would be awesome if you could get that sourcecode - everyone needs this