Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function setup()
- --[[ Sphere generator v1
- This is an app made in Codea written by Muffincoder on Codeas' forum
- You may use this code for whatever you like, I would be glad to see
- whatever you come up with using this or use this for.
- Also note that the algorithm I came up with is not optimal, it works, that's it.
- If you improve the algorithm then please tell me what and how you did it.
- This was purely a fun project that I created on my pastime. Enjoy!
- ]]
- -- These define the amount of fragments vertically and horizontally
- segmentsH = 100
- segmentsV = 30
- --The radius of the sphere
- size = 100
- --This is the texture for the sphere, use a rectangular texture for example an image of earth.
- texture = "Documents:earth"
- --Also note that the sphere can be either colored with random colors or textured
- --This is made possible with the use of 2 shaders, one for pure color and one basic texture shader
- colorOnlyShader = shader([[
- uniform mat4 modelViewProjection;
- attribute vec4 position;
- attribute vec4 color;
- varying lowp vec4 vColor;
- void main()
- {
- vColor = color;
- gl_Position = modelViewProjection * position;
- }
- ]],[[
- precision highp float;
- varying lowp vec4 vColor;
- void main()
- {
- gl_FragColor = vColor;
- }
- ]])
- textureShader = shader([[
- uniform mat4 modelViewProjection;
- attribute vec4 position;
- attribute vec4 color;
- attribute vec2 texCoord;
- varying lowp vec4 vColor;
- varying highp vec2 vTexCoord;
- void main()
- {
- vColor = color;
- vTexCoord = texCoord;
- gl_Position = modelViewProjection * position;
- }
- ]],[[
- precision highp float;
- uniform lowp sampler2D texture;
- varying lowp vec4 vColor;
- varying lowp vec2 vTexCoord;
- void main()
- {
- lowp vec4 col = texture2D(texture, vTexCoord) * vColor;
- gl_FragColor = col;
- }
- ]])
- --Variable init
- meshS = mesh()
- verts = {}
- vertices = {}
- colors = {}
- texels = {}
- texCoords = {}
- parameter.integer("segmentsH",5,150,segmentsH)
- parameter.integer("segmentsV",3,150,segmentsV)
- parameter.action("generateSphere",generateSphere)
- parameter.boolean("randomColors",true)
- parameter.integer("dist",-1000,0,-350)
- parameter.integer("rotX",0,360,0)
- parameter.integer("rotY",0,360,0)
- parameter.integer("rotZ",0,360,0)
- generateSphere()
- end
- function generateSphere()
- --Calculate how big of an angle each fragment of the sphere has
- local segmentHangle = (2*math.pi)/segmentsH
- local segmentVangle = (math.pi/(segmentsV+1))
- --Reset arrays if set already, or initialize them if this is the first run
- meshS = mesh()
- verts = {}
- vertices = {}
- colors = {}
- texels = {}
- texCoords = {}
- --First part is to generate each unique vertex for the sphere
- --Starting with the topmost vertex
- table.insert(verts,vec3(0,size,0))
- table.insert(texels,vec2(0.5,1.0))
- for i=1,segmentsV do
- local texelY = 1-(i / segmentsV)*((segmentsV-1)/segmentsV)
- for j=1,segmentsH do
- --Radius parameter exposed for easier manipulation of the surface
- -- you can for example add some noise here to make the surface 'grainy'
- local length = size
- local posX = math.cos(j*segmentHangle)*length*math.cos(math.pi/2 + (i*segmentVangle))
- local posZ = math.sin(j*segmentHangle)*length*math.cos(math.pi/2 + (i*segmentVangle))
- local posY = math.sin(math.pi/2 + (i*segmentVangle))*length
- local texelX = 1-(j / segmentsH)
- table.insert(verts,vec3(posX,posY,posZ))
- table.insert(texels,vec2(texelX,texelY))
- end
- end
- --And ending with the bottom vertex
- table.insert(verts,vec3(0,-size,0))
- table.insert(texels,vec2(0.5,0.0))
- print("Nr of unique vertices: "..#verts)
- print("Nr of unique texels: "..#texels)
- --Then generate the mesh out of the unique vertices
- for i=1,#verts do
- --[[I split the sphere into 3 parts;
- A Top part, a middle part and a bottom part.
- -The top and bottom ones are pretty much the same but the latter turned upside down.
- -The top vertex and the first ring of vertices assemble a circle using
- triangles that all share the top vertex. The same for the bottom part.
- -The middle part is just a mesh of the remaining vertices
- ]]
- --Top part
- if i == 1 then
- for j=1,segmentsH-1 do
- local curIndex = i + j
- table.insert(vertices,verts[i])
- table.insert(vertices,verts[curIndex+1])
- table.insert(vertices,verts[curIndex])
- table.insert(texCoords,texels[i])
- table.insert(texCoords,texels[curIndex+1])
- table.insert(texCoords,texels[curIndex])
- end
- table.insert(vertices,verts[i])
- table.insert(vertices,verts[i+1])
- table.insert(vertices,verts[i+segmentsH])
- table.insert(texCoords,texels[i])
- table.insert(texCoords,texels[i+1])
- table.insert(texCoords,vec2(1.0,texels[i+segmentsH].y))
- i = i + segmentsH
- --Middle part
- elseif i > segmentsH and i < #verts then
- local lastRow = i - segmentsH
- local thisRow = ((i-1) % segmentsH)+1
- if lastRow > 1 then
- table.insert(vertices,verts[i])
- table.insert(vertices,verts[lastRow+1])
- table.insert(vertices,verts[lastRow])
- if thisRow == 1 then
- table.insert(texCoords,vec2(1.0,texels[i].y))
- table.insert(texCoords,texels[lastRow+1])
- table.insert(texCoords,vec2(1.0,texels[lastRow].y))
- else
- table.insert(texCoords,texels[i])
- table.insert(texCoords,texels[lastRow+1])
- table.insert(texCoords,texels[lastRow])
- end
- end
- if i+1 < #verts then
- table.insert(vertices,verts[i])
- table.insert(vertices,verts[i+1])
- table.insert(vertices,verts[lastRow+1])
- if thisRow == 1 then
- --table.insert(texCoords,vec2(1.0,texels[lastRow].y))
- table.insert(texCoords,vec2(1.0,texels[i].y))
- table.insert(texCoords,texels[i+1])
- table.insert(texCoords,texels[lastRow+1])
- else
- table.insert(texCoords,texels[i])
- table.insert(texCoords,texels[i+1])
- table.insert(texCoords,texels[lastRow+1])
- end
- end
- --Bottom part
- if i == (#verts-segmentsH) then
- for j=1,segmentsH-1 do
- local curIndex2 = i + j
- table.insert(vertices,verts[#verts])
- table.insert(vertices,verts[curIndex2])
- table.insert(vertices,verts[curIndex2-1])
- table.insert(texCoords,texels[#verts])
- table.insert(texCoords,texels[curIndex2])
- table.insert(texCoords,texels[curIndex2-1])
- end
- table.insert(vertices,verts[#verts])
- table.insert(vertices,verts[#verts-1])
- table.insert(vertices,verts[#verts-segmentsH])
- table.insert(texCoords,texels[#verts])
- table.insert(texCoords,vec2(1.0,texels[#verts-1].y))
- table.insert(texCoords,texels[#verts-segmentsH])
- i = i + segmentsH
- end
- end
- end
- meshS.vertices = vertices
- meshS.texCoords = texCoords
- if randomColors then
- for i=1,#vertices,3 do-- Color each triangle with a different color
- randomCol(3)
- end
- meshS.colors = colors
- meshS.shader = colorOnlyShader
- meshS.texture = ""
- else
- meshS:setColors(255,255,255,255)
- meshS.texture = texture
- meshS.shader = textureShader
- end
- print("Final mesh vertex count: "..#vertices)
- print("Color array length: "..#colors)
- print("Tex-coord array length: "..#texCoords)
- print("---------")
- end
- function draw()
- background(0, 0, 0, 255)
- fill(255, 255, 255, 255)
- --Camera setup
- camera(0,0,5, 0,0,0, 0,1,0)
- perspective(45,WIDTH/HEIGHT,0.1,10000)
- --Translate the sphere a bit into the screen
- translate(0,0,dist)
- --And rotate the object
- rotate(rotX,1,0,0)
- rotate(rotY+ElapsedTime*10,0,1,0)
- rotate(rotZ,0,0,1)
- --Draw sphere
- meshS:draw()
- end
- function randomCol(n)
- local col = vec4(math.random(),math.random(),math.random(),1.0)
- for q=1,n do
- table.insert(colors,col)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement