Howdy, Stranger!

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

Procedurally Creating Objects

edited March 2018 in Questions Posts: 11

I understand creating objects one by one, but I can’t seem to understand how to create objects in bulk. From what I’ve looked at, you need a table to tell all the objects of a class apart, but that’s as far as I can understand....

Tagged:

Comments

  • dave1707dave1707 Mod
    Posts: 7,554

    @MalikWilburn If you know how to create an object and you know they go in tables then you’re 99% of the way there. Here’s an example of creating Craft spheres. You can create a single or multiple spheres without a table, but if you want to modify something about them, then you need a table. He an example of creating a single or multiple spheres, and then multiple spheres using a table. Then using the spheres in the table, I’m changing their colors.

    displayMode(FULLSCREEN)
    
    function setup()
        assert(craft, "Please include Craft as a dependency")
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")        
        scene = craft.scene()
        skyMaterial=scene.sky.material
        skyMaterial.sky=color(158, 202, 223, 255)
        skyMaterial.horizon=color(98, 166, 114, 255)
        scene.sun.rotation=quat.eulerAngles(20,45,-30)
        v=scene.camera:add(OrbitViewer, vec3(0,0,0), 200, 0, 1000)
    
        -- create a single sphere
        createSphere(vec3(0,0,0),3)
    
        -- create multiple spheres without a table
        for z=1,20 do
            createSphere(vec3(math.random(-50,50),
                math.random(-50,50),math.random(-50,50)))       
        end
    
        -- create multiple spheres using a table
        tab={}
        for z=1,20 do
            table.insert(tab,createSphere(vec3(math.random(-50,50),
                math.random(-50,50),math.random(-50,50))))      
        end
    end
    
    function draw()
        update(DeltaTime)
        scene:draw()
    end
    
    function update(dt)
        scene:update(dt)
    
        -- change the sphere colors using the spheres in the table
        for z=1,#tab do
            tab[z].material.diffuse=color(math.random(255),
                math.random(255),math.random(255))
        end
    end
    
    function createSphere(p)
        local pt=scene:entity()
        pt.position=vec3(p.x,p.y,p.z)
        pt.model = craft.model.icosphere(3,2)
        pt.material = craft.material("Materials:Specular")
        pt.material.diffuse=color(255,0,0)
        return(pt)
    end
    
  • Posts: 1,205

    @dave1707 - very impressive, but I have a problem just with spheres - on how to texture a single sphere. That is wrap in 3D rather than tile. Looking at the documentation for craft I’m sure I saw a command for unwrapping an object, say an icosahedron, but I can’t seem to locate it now. All I can find is

    u, v = myModel:uv( index )
    myModel:uv( index, p )
    myModel:uv( index, u, v )

    I’d like to be able to take a Craft icosphere and texture it or build up my own sphere vertices list and texture it as a Craft object.

    Any ideas?

  • dave1707dave1707 Mod
    Posts: 7,554

    @Bri_G I haven’t tried wrapping a craft sphere yet. I’ll look into it later. Maybe one of the Craft examples has something.

  • Posts: 1,205

    @dave1707 - there is an example in theCraft demos (World Generator) but it involves exagerated terra forming for the texture, superb but way out of my league. May be able to pick out the basics so will revisit it.

  • Posts: 430

    @Bri_G My MeshExt class has a sphere creator which uses a standard texture mapping. I've used it to create star backgrounds and planets. I can dig up some code if you're interested.

  • Posts: 1,205
    @LoopSpace - thanks for the offer, if you have something I'd be very interested. I am currently using JMV38s planet creator which is great. Anyone interested in an excellent tutorial should chase it up. He has both simple and optimised models together with shadow.

    My main interest is in using it alongside Craft, I think it's a case of integrating the planet model produced with the Craft Scene.

    Looking to produce a video of what I'm doing but don't hold your breath.

    I'll check out your MeshExt class - thanks for the pointer.
  • dave1707dave1707 Mod
    Posts: 7,554

    @Bri_G Here’s a texture example that I created from a sphere example I posted long ago. I couldn’t find my original post, it must be in someone else’s discussion. This doesn’t use Craft, that’s something I’ll have to try later. The texture image should be twice as wide as it is high so that it doesn’t appear stretched. I created a texture example that is the correct size, but the other texture examples aren’t. Slide the image slider for the other examples and the Dist slider to move in or out. You can also move the Angle X or Y slider.

    function setup()
        myTexture=image(1024,512)
        setContext(myTexture)
        background(170, 198, 223, 255)
        fill(0, 19, 255, 255)
        fontSize(40)
        text("This is my texture example, move image slider for more.",512,256)
        fill(255,0,0)
        ellipse(300,128,100,50)
        fill(0,255,0)
        ellipse(900,128,50,100)
        fill(255,255,0)
        rect(640,320,128,64)
        stroke(0)
        strokeWidth(3)
        for z=0,1024,64 do
            line(z,0,z,512)
        end
        for z=0,512,32 do
            line(0,z,1024,z)
        end
        setContext()
    
        img={myTexture,"Cargo Bot:About Info Panel","Cargo Bot:Cargo Bot Title",
            "Cargo Bot:Startup Screen","Surfaces:Desert Cliff Color",
            "Surfaces:Desert Cliff Height","Surfaces:Basic Bricks Roughness",
            "Surfaces:Stone Brick Height","Environments:Sunny Up"}
        level=50
        parameter.number("AngleX",0,360,90)
        parameter.number("AngleY",0,360,180) 
        parameter.integer("Dist",300,1500,600)
        parameter.integer("image",1,#img,1)
        AngleZ=180
        tex,vert,tab={},{},{}
        radius=100
        M,N=level,level
        -- calculate sphere points
        for n=0,N do
            tab[n]={}
            for m=0,M do
                x=radius * math.sin(math.pi * m/M) * math.cos(2*math.pi * n/N)
                y=radius * math.sin(math.pi * m/M) * math.sin(2*math.pi * n/N)
                z=radius * math.cos(math.pi * m/M)
                tab[n][m]=vec3(x,y,z)
            end
        end
        hor=0
        ad=1/level
        -- calculate vertices and texcoord from sphere points
        for n=0,N-1 do
            ver=1
            for m=0,M-1 do
                table.insert(vert,tab[n][m])
                table.insert(vert,tab[n][m+1])
                table.insert(vert,tab[n+1][m+1])  
                table.insert(vert,tab[n][m])
                table.insert(vert,tab[n+1][m])
                table.insert(vert,tab[n+1][m+1])
                table.insert(tex,vec2(hor,ver+ad))
                table.insert(tex,vec2(hor,ver))
                table.insert(tex,vec2(hor+ad,ver))
                table.insert(tex,vec2(hor,ver+ad))
                table.insert(tex,vec2(hor+ad,ver+ad))
                table.insert(tex,vec2(hor+ad,ver))
                ver=ver-ad
            end
            hor=hor+ad
        end
        sphere=mesh()    
        sphere.vertices=vert
        sphere.texCoords=tex
        sphere:setColors(255,255,255,255)   
    end
    
    function draw()  
        background(223, 211, 142, 255)
        sprite(img[image],150,150,200)
        perspective()
        camera(Dist,0,0,0,0,0,0,1,0)
        rotate(AngleX,1,0,0)
        rotate(AngleY,0,1,0)
        rotate(AngleZ,0,0,1)
        sphere.texture=img[image]
        sphere:draw()
        AngleZ=AngleZ-.3
    end
    
  • Posts: 1,205

    @dave1707 - thanks for the code, that’s a very neat example. I’ve started playing around with it and using it for texture viewing now. Hope I can link this into Craft somehow.

  • dave1707dave1707 Mod
    Posts: 7,554

    @Bri_G I don’t think it can be used with Craft. Run this code to see how an icosphere is created. My code creates a sphere made up of rectangles and then splits the rectangle into 2 triangles to be used by mesh. Think of latitude, longitude rectangles. The icosphere is made up of triangles, but the triangles don’t make a bunch of rectangles. That means it wouldn’t match up to a rectangular texture map. So at this point I don’t know how to map it.

    displayMode(FULLSCREEN)
    
    function setup()
        assert(craft, "Please include Craft as a dependency")
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")        
        scene = craft.scene()
        skyMaterial=scene.sky.material
        skyMaterial.sky=color(158, 202, 223, 255)
        skyMaterial.horizon=color(98, 166, 114, 255)
        scene.sun.rotation=quat.eulerAngles(20,45,-30)
        v=scene.camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 1000)
        v.rx=0
        v.ry=-88
        createSphere(vec3(0,0,0))
    end
    
    function draw()
        update(DeltaTime)
        scene:draw()
        fill(255)
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function createSphere(p)
        pt=scene:entity()
        pt.position=vec3(p.x,p.y,p.z)
        pt.model = craft.model.icosphere(30,1,true)
        pt.material = craft.material("Materials:Standard")
        pt.material.diffuse=color(255,0,0)
    end
    
  • Posts: 430

    I have a vague recollection that the icosphere model doesn't set texture coordinates so it can't be used with a texture unless you figure out what they should be (but if you figure those out, there'd be no difference to using a regular sphere texture).

    Here's the code from my roller coaster project that creates a star sphere:

            local galaxy = PseudoMesh()
            galaxy:addSphere({radius = 100})
            galaxy:invertNormals()
            e = scene:entity()
            e.model = galaxy:toModel()
            e.material = craft.material("Materials:Basic")
            e.material.map = "Project:starmap_small"
    

    It uses my PseudoMesh and MeshExt libraries. The texture is a star map from NASA. So, quite simple, I hope you'll agree.

Sign In or Register to comment.