Howdy, Stranger!

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

Can you inspect a model to find its skin?

edited April 15 in Codea Craft Posts: 1,175

I’m creating scenes that can have any number of entities.

Each can have any of the models in the builtin craft.models.

Each needs to use a glow effect at any given time, like in this demo.

In the demo, each robot’s glow relies on materials prepared like this:


robot.model = craft.model(asset.builtin.Blocky_Characters.Robot) robot.material = craft.material(asset.builtin.Materials.Specular) robot.material.map = readImage(asset.builtin.Blocky_Characters.RobotSkin)

Notice that for material.map I have to directly read the image used for the model’s skin.

But as I said, in the real project, entities can use any craft model, not just robots.

So is there a way to access this skin dynamically, in other words, without knowing what it is beforehand?

Because if there isn’t, in order to be able to use this effect in my project, I think I will need to manually hand-code the image that goes with every single craft model.

And if the models or skins are ever changed in the future the project will break.

So, like, that’s not good, man. :)

To use this approach, I think I have to be able to do something like this:


function assignMaterial(thisEntity) local skinImage = thisEntity.skin thisEntity.material = craft.material(asset.builtin.Materials.Specular) thisEntity.material.map = skinImage end

...but I can’t do that because thisEntity.skin isn’t an attribute that actually exists.

Is there some way to do this without hand-coding the value for skin for each model?

Comments

  • dave1707dave1707 Mod
    Posts: 9,248

    @UberGoober You could probably put them in a table along with other info and use that to identify what material you want.

  • Posts: 1,175

    @dave1707 wouldnt I still have to hand-code them, leaving them open to breaking the entire code if updates change anything referenced?

  • Posts: 2,228
    @UberGoober - the image for the model will be loaded with the other model files, probable a png file. If you could identify it you could probably use saveImage() - but, the models loaded are probably licensed so you may not be able to use it.
    You may be able to load a single colour png image as a texture - if so you could also load a varicoulored mesh texture to identify the key vertices on the model then colour the model section as needed. You need a graphics package to do so.
  • Posts: 1,175

    @Bri_G I'm not sure I get what you’re saying, are you suggesting creating a routine that reads every single image in the Codea built-ins, and then compares it to the model to identify which image is that model’s skin?

    Because if that’s not what you’re suggesting, don’t I still have to know the file name beforehand?

  • Posts: 2,228
    @UberGoober - you seem concerned with losing models/skins and not being able to retain them to avoid their loss in updates.Just suggesting how you could retain the textures or at least the texture map to edit if needed. Not for all - just the ones you hoped to retain.
  • dave1707dave1707 Mod
    Posts: 9,248

    @UberGoober Here's an example with a table. I can identify each character by the name I gave them in the first position of the table. Does this help in what you’re after.

    function setup()
        mtab={
            {   "robot",
                asset.builtin.Blocky_Characters.Robot,
                asset.builtin.Materials.Specular,
                asset.builtin.Blocky_Characters.RobotSkin
            },
            {   "man",
                asset.builtin.Blocky_Characters.Man,
                asset.builtin.Materials.Specular,
                asset.builtin.Blocky_Characters.ManSkin
            },
            {   "orc",
                asset.builtin.Blocky_Characters.Orc,
                asset.builtin.Materials.Specular,
                asset.builtin.Blocky_Characters.OrcSkin
            },
            {   "woman",
                asset.builtin.Blocky_Characters.Woman,
                asset.builtin.Materials.Specular,
                asset.builtin.Blocky_Characters.WomanSkin
            },
            {   "soldier",
                asset.builtin.Blocky_Characters.Soldier,
                asset.builtin.Materials.Specular,
                asset.builtin.Blocky_Characters.SoldierSkin
            },
            }
    
        tab={}
        scene = craft.scene()
        scene.sun.rotation=quat.eulerAngles(30,45,30)
        v=scene.camera:add(OrbitViewer, vec3(0,0,0), 200, 0, 1000)
        v.ry=180
    
        cameraComponent = scene.camera:get(craft.camera)
        cameraComponent.hdr = true
        cameraComponent.colorTextureEnabled = true
    
        bloom = craft.bloomEffect()
        cameraComponent:addPostEffect(bloom)
    
        bloom.threshold = 4
        bloom.intensity = 1.2
        bloom.softThreshold = 0.4
        bloom.iterations = 8
    
        for z=1,50 do
            local robot = scene:entity()
            v=z%5+1
            robot.model = craft.model(mtab[v][2])
            robot.material = craft.material(mtab[v][3])
            robot.material.map = readImage(mtab[v][4])
    
            x=math.random(-50,50)
            y=math.random(-50,50)
            z=math.random(-50,50)
            robot.position = vec3(x,y,z)
            table.insert(tab,{rb=robot,x=x,y=y,z=z,r=0,a=false})
        end
        parameter.integer("pos",1,#tab,position)
        parameter.integer("Rotate",-180,180,0,rotate)
        parameter.boolean("int",false,intensity)
    end
    
    function update(dt)
        scene:update(dt)
    end
    
    function rotate()
        tab[pos].r=Rotate
    end
    
    function draw()
        update(DeltaTime)
        tab[pos].rb.eulerAngles = vec3(0,tab[pos].r, 0)
        scene:draw()
    end
    
    function position()
        Rotate=tab[pos].r
        int=tab[pos].a
    end
    
    function intensity()
        if int then
            tab[pos].rb.material.diffuse = vec3(2.5,1.5,4)
            tab[pos].a=true
        else
            tab[pos].rb.material.diffuse = vec3(1,1,1)
            tab[pos].a=false
        end
    end
    
  • Posts: 1,175

    In case anyone else has this issue: you can dynamically get the material that’s using the skin on any of the default models with the technique @piinthesky shows here:

    https://codea.io/talk/discussion/comment/83517#Comment_83517

    ...the secret is the undocumented function entity.model:getMaterial(0)

  • SimeonSimeon Admin Mod
    Posts: 5,613

    @UberGoober I've made a note to write documentation for this and other Craft functions

  • Posts: 631

    @Simeon as reported in the orignal thread
    https://codea.io/talk/discussion/10831/add-transparency-to-a-3d-obj-mtl-model
    i did not actually suceed to reproduce what @John showed and would really like to do so! Help please @John.

  • Posts: 1,175

    @Simeon when you document it, please give significant emphasis to the apparent fact that model:getMaterial(i) is indexed starting with 0, unlike everything else in lua. Since it’s at variance with the whole rest of the language, I think it will be very easy for people to get tripped up by this.

  • SimeonSimeon Admin Mod
    Posts: 5,613

    @UberGoober given that this is undocumented, I think we should change it to a 1-based index to match the rest of the language

  • Posts: 1,175
    @Simeon oh I absolutely agree, I didn’t know that was an option.
Sign In or Register to comment.