Created
March 12, 2013 19:46
-
-
Save tnlogy/5146337 to your computer and use it in GitHub Desktop.
IsoSphere with texture mapping
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# Main | |
-- IsoSphere | |
-- Use this function to perform your initial setup | |
function setup() | |
parameter.integer("Divisions", 0,5,1, createSphere) | |
parameter.number("H",-10,10,0) | |
R = 0 | |
end | |
function createSphere() | |
is = IsoSphere(Divisions) | |
ga = IsoSphere(4) | |
ga.m.shader = nil | |
ga.m.texture = readImage("Documents:Galaxy") | |
end | |
-- This function gets called once every frame | |
function draw() | |
-- This sets a dark background color | |
background(40, 40, 50) | |
camera(0,H,20, 0,0,0) | |
perspective(45) | |
rotate(R, 0,1,0) | |
is:draw() | |
scale(100) | |
ga:draw() | |
end | |
function touched(touch) | |
if touch.state == MOVING then | |
R = R + touch.deltaX | |
end | |
end | |
--# IsoSphere | |
-- Based on http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html | |
IsoSphere = class() | |
function IsoSphere:init(divisions) | |
local t = (1.0 + math.sqrt(5.0)) / 2.0; | |
local vs = { | |
vec3(-1,t,0),vec3(1,t,0),vec3(-1,-t,0),vec3(1,-t,0), | |
vec3(0,-1,t),vec3(0,1,t),vec3(0,-1,-t),vec3(0,1,-t), | |
vec3(t,0,-1),vec3(t,0,1),vec3(-t,0,-1),vec3(-t,0,1) | |
} | |
local ts = { | |
vs[1],vs[12],vs[6], -- 5 faces around vs[1] | |
vs[1],vs[6],vs[2], | |
vs[1],vs[2],vs[8], | |
vs[1],vs[8],vs[11], | |
vs[1],vs[11],vs[12], | |
vs[2],vs[6],vs[10], -- 5 adjacent faces | |
vs[6],vs[12],vs[5], | |
vs[12],vs[11],vs[3], | |
vs[11],vs[8],vs[7], | |
vs[8],vs[2],vs[9], | |
vs[4],vs[10],vs[5], -- 5 faces around vs[4] | |
vs[4],vs[5],vs[3], | |
vs[4],vs[3],vs[7], | |
vs[4],vs[7],vs[9], | |
vs[4],vs[9],vs[10], | |
vs[5],vs[10],vs[6], -- 5 adjacent faces | |
vs[3],vs[5],vs[12], | |
vs[7],vs[3],vs[11], | |
vs[9],vs[7],vs[8], | |
vs[10],vs[9],vs[2] | |
} | |
ts = self:divide(divisions or 0, ts) | |
self.m = mesh() | |
self.m.shader = lightShader | |
self.m.vertices = ts | |
self.m:setColors(255,255,255,255) | |
local nor = self.m:buffer("normal") | |
nor:resize(#ts) | |
local uvs = {} | |
local calcUV = function(v1, v2, v3) | |
local diff = function(a,b) | |
a = (b - a)/math.pi | |
if math.abs(a) >= 1 then | |
if a >= 0 then a = a - 2 else a = a + 2 end | |
end | |
return a | |
end | |
local a = math.atan2(v1.z,-v1.x) | |
local b = math.asin(-v1.y) | |
local uv1 = vec2(.5 + a/(math.pi*2), .5 - b/math.pi) | |
local uv2 = vec2(uv1.x + diff(a, math.atan2(v2.z,-v2.x))/2, | |
uv1.y - diff(b, math.asin(-v2.y))) | |
local uv3 = vec2(uv1.x + diff(a, math.atan2(v3.z,-v3.x))/2, | |
uv1.y - diff(b, math.asin(-v3.y))) | |
return uv1,uv2,uv3 | |
end | |
for i=1,#ts,3 do | |
local v1,v2 = ts[i]:normalize(),ts[i+1]:normalize() | |
local v3 = ts[i+2]:normalize() | |
local uv1,uv2,uv3 = calcUV(v1,v2,v3) | |
nor[i],nor[i+1],nor[i+2] = v1,v2,v3 | |
table.insert(uvs, uv1) | |
table.insert(uvs, uv2) | |
table.insert(uvs, uv3) | |
end | |
self.m.texCoords = uvs | |
-- http.request( | |
-- 'http://www.evl.uic.edu/pape/data/Earth/2048/PathfinderMap.jpg', | |
-- function(data) self.m.texture = data end) | |
self.m.texture = readImage("Documents:Earth") | |
end | |
function IsoSphere:divide(divisions, ts) | |
local mp = function (a, b) -- mid point | |
return ((a+b)/2) | |
end | |
for i=1,divisions do | |
local vs = {} | |
for j=1,#ts,3 do | |
local v1,v2,v3 = ts[j],ts[j+1],ts[j+2] | |
local a,b,c = mp(v1,v2),mp(v2,v3),mp(v3,v1) | |
local nvs = {v1,a,c, v2,b,a, v3,c,b, a,b,c} | |
for k,v in ipairs(nvs) do | |
table.insert(vs,v:normalize()*2) | |
end | |
end | |
ts = vs | |
end | |
return ts | |
end | |
function IsoSphere:draw() | |
if self.m.shader then | |
self.m.shader.light = vec3(-Gravity.x,-Gravity.y,0) | |
end | |
self.m:draw() | |
end | |
--# LightShader | |
lightShader = shader() | |
lightShader.vertexProgram = [[ | |
uniform mat4 modelViewProjection; | |
uniform vec3 light; | |
attribute vec4 position; | |
attribute vec4 color; | |
attribute vec2 texCoord; | |
attribute vec3 normal; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
void main() | |
{ | |
vColor = color; | |
vTexCoord = vec2(texCoord.x,texCoord.y); | |
lowp vec4 nor = modelViewProjection * vec4(normal,0); | |
lowp float vShade = (dot(nor.xyz,light)+0.2)/1.2; | |
if (vShade >1.0) {vShade=1.0;} | |
if (vShade <0.1) {vShade=0.1;} | |
vColor.rgb = vColor.rgb * vShade; | |
gl_Position = modelViewProjection * position; | |
} | |
]] | |
lightShader.fragmentProgram = [[ | |
uniform lowp sampler2D texture; | |
varying lowp vec4 vColor; | |
varying highp vec2 vTexCoord; | |
void main() | |
{ | |
gl_FragColor = texture2D(texture, vTexCoord)* vColor; | |
} | |
]] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment