Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Icosphere

edited April 2020 in Codea Craft Posts: 2,099

@Simeon - @John
Can someone refresh my memory - I recollect going through a whole series of sphere mapping alternatives to the one used in Craft some great work by forum members to create excellent detailed images. What I can’t remember was if we incorporated any learning in the Craft icosphere model. My reason being I just set up a textured sphere and tried a few images to check it out and found each sphere had a zip (see attached image). Do we need to add a new model or do I need better textures?

Tagged:

Comments

  • Posts: 609

    @Bri_G, yes, i think the native Codea icosphere is not correct. I therefore use the @LoopSpace version which is better. Someday i hope @John will fix that. I guess the sphere used in Shade is correct?

  • dave1707dave1707 Mod
    edited April 2020 Posts: 9,079

    @Bri_G Here's my version that I posted long ago. You can also zoom in to see the sphere from the inside.

    PS. I found the original link where I was creating the code.

    https://codea.io/talk/discussion/9133/craft-sphere-texture#latest
    
    displayMode(FULLSCREEN)
    
    function setup()  
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")        
        scene = craft.scene()
        v=scene.camera:add(OrbitViewer, vec3(0,0,0), 700, 0, 1000)
    
        myImg=readImage(asset.builtin.Surfaces.Basic_Bricks_Color)
    
        s1=createSphere(vec3(0,0,0),200,5,false,true,myImg)
    end
    
    function draw()
        update(DeltaTime)
        scene:draw()
    end
    
    function update(dt)
        scene:update(dt)
        s1.rotation = quat.eulerAngles(-90,0,0)
    end
    
    function createSphere(pos,size,level,flat,ins,image)
        local s=scene:entity()
        s.position=vec3(0,0,0)
        s.model = craft.model.icosphere(size,level,flat)
        s.material = craft.material(asset.builtin.Materials.Standard) 
        icoTexture(s,ins,image)
        return s
    end
    
    function icoTexture(sph,inside,img)
        local seam=0
        local ax,bx,cx,ay,by,cy,c,lat,lon  
        local posTab=sph.model.positions
        local pTab,cTab,nTab,llTab,uvTab,colTab,norTab,iTab={},{},{},{},{},{},{},{}
        local deg=math.deg
        local asin=math.asin
        local atan2=math.atan2
        sph.material.map=img 
    
        -- create tables for rounded icospheres        
        if not flat then
            iTab=sph.model.indices
            pTab=sph.model.positions
            cTab=sph.model.colors
            nTab=sph.model.normals  
            for a,b in pairs(iTab) do
                posTab[a]=pTab[b]
                colTab[a]=cTab[b]
                norTab[a]=nTab[b]
                iTab[a]=a
            end
        end 
    
        -- convert sphere positions to latitude and longitude
        for a,b in pairs(posTab) do
            c=b:normalize()
            lat=deg(asin(c.z))+90
            lon=deg(atan2(c.y,c.x))
            llTab[a]=vec2(lon,lat)     -- save lon, lat in table
            if lon//1==-149 then    -- get exact value of seam
                seam=lon
            end
        end 
    
        -- shift points on the left side of the seam to the right side 
        for a,b in pairs(llTab) do        
            b.x=b.x-seam
            if b.x<-.01 then
                b.x=b.x+360
            end
        end 
    
        -- shift individual points of triangle if needed  
        for z=1,#llTab,3 do
            ax,ay=llTab[z].x,llTab[z].y
            bx,by=llTab[z+1].x,llTab[z+1].y
            cx,cy=llTab[z+2].x,llTab[z+2].y
            if ax>250 or bx>250 or cx>250 then
                if ax<.01 then 
                    ax=360
                end
                if bx<.01 then
                    bx=360
                end
                if cx<.01 then
                    cx=360
                end  
            end  
            if ay==0 or ay==180 then
                ax=(bx+cx)*.5
            elseif by==0 or by==180 then
                bx=(ax+cx)*.5
            elseif cy==0 or cy==180 then
                cx=(ax+bx)*.5
            end  
    
            -- create uv table
            uvTab[z]=vec2(ax/360,ay/180)
            uvTab[z+1]=vec2(bx/360,by/180)
            uvTab[z+2]=vec2(cx/360,cy/180)
        end 
    
        -- reset tables 
        sph.model.uvs=uvTab
    
        if not flat then
            sph.model.indices=iTab
            sph.model.positions=posTab
            sph.model.colors=colTab
            sph.model.normals=norTab
        end
    
        --update indices table for inside view    
        if inside then
            iTab=sph.model.indices
            for z=#sph.model.indices,1,-1 do
                iTab[#iTab+1]=iTab[z]
            end
            sph.model.indices=iTab
        end
    end
    
  • edited April 2020 Posts: 2,099
    @piinthesky @dave1707 - thanks for that, confirmed my own recollection. I remember @LoopSpace tried a lot of different approaches shame we didn''t get an upgrade there. The Shade version does look to be complete, as you say, and should be transferable. In the meantime anyone know what the possible problems are in using sprites, meshes and Craft together?

    P.s. @dave1707 - thanks for the link and code, I need to re-read that to get back up to speed.
Sign In or Register to comment.