Geospheres - The better sphere

Blitz3D Forums/Blitz3D Programming/Geospheres - The better sphere

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