Howdy, Stranger!

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

How to rotate the craft.model around the specified axis?

edited January 2 in Codea Craft Posts: 190

How to rotate the craft.model around the specified axis?

Hi, guys,I am back to learn the craft and found many questions. Here is the one.

I read the built-in examples Block Library and try to use the technique in it.

In the built-in help docs, I found that only craft.model.cube and craft.model.plane have the "offset" parameter, with which can easily make the model rotate around any specified axis.

But craft.model.icosphere and the loaded model which using craft.model("asset model") have not the "offset", how to rotate them like the craft.model.cube?

Here is the demo video:

https://youtu.be/zWJ47JgE-_M

Below is the code:

function setup()
    -- Create a new craft scene
    scene = craft.scene()
    scene.ambientColor = color(218, 158, 79)
    scene.sky.active = false

    -- Setup camera and lighting
    scene.sun.rotation = quat.eulerAngles(125, 125, 0)

    assert(OrbitViewer, "Please include Cameras project as a dependency")
    gViewer = scene.camera:add(OrbitViewer, vec3( 2.0,  0.5,  0.5), 8, 1, 400)
    gViewer.rx=45
    gViewer.ry=-45

    myChest = Chest()
end

function update(dt)
    -- Update the scene (physics, transforms etc)
    scene:update(dt)
    myChest:update()
end

-- Called automatically by codea 
function draw()
    update(DeltaTime)

    -- Draw the scene
    scene:draw()    
end


Chest = class()

function Chest:init()
    e = self.entity
    self.base = scene:entity()
    self.base.parent = e
    self.base.position = vec3(0.5, 0.3, 0.5)
    local r = self.base:add(craft.renderer, craft.model.cube(vec3(0.8,0.6,0.8)))
    r.material = craft.material(asset.builtin.Materials.Specular)
    r.material.diffuse = color(133, 79, 30)

    self.top = scene:entity()
    self.top.parent = e
    self.top.position = vec3(0.1, 0.6, 0.1)
    print("local=",self.top.position, " world=", self.top.worldPosition)
    local r2 = self.top:add(craft.renderer, craft.model.cube(vec3(0.8,0.2,0.8),vec3(0.4,0.1,0.4)))
    print("local=",self.top.position," world= ",self.top.worldPosition)
    r2.material = craft.material(asset.builtin.Materials.Specular)
    r2.material.diffuse = color(66, 47, 30, 255)
    self.angle = 0
    self.y = 0.6

    self.ball = scene:entity()
    self.ball.position = vec3(1.5, 0.3, 0.5)
    local r3 = self.ball:add(craft.renderer, craft.model.icosphere(0.3))
    r3.material = craft.material(asset.builtin.Materials.Specular)
    r3.material.diffuse = color(133, 124, 30)

    self.obj = scene:entity()
    self.obj.position = vec3(2.5, 0.3, 0.5)
    self.obj.scale = vec3(0.5, 0.5, 0.5)
    local r4 = self.obj:add(craft.renderer, craft.model(asset.builtin.Primitives.RoundedCube))
    r4.material = craft.material(asset.builtin.Materials.Specular)
    r4.material.diffuse = color(30, 133, 101)

    self.floor = scene:entity()
    self.floor.parent = e
    self.floor.position = vec3(0.1, 0.6, 0.1)
    local r5 = self.floor:add(craft.renderer, craft.model.plane(vec2(1.8,1.8),vec3(0.9,0.0,0.9)))
    r5.material = craft.material(asset.builtin.Materials.Specular)
    r5.material.diffuse = color(46, 66, 30)

    touches.addHandler(self, -1, false)
end

function Chest:update()
    self.top.rotation = quat.eulerAngles(0,  0, self.angle)
    self.ball.rotation = quat.eulerAngles(0,  0, self.angle)
    self.obj.rotation = quat.eulerAngles(0,  0, self.angle)
    self.floor.rotation = quat.eulerAngles(0,  0, self.angle)

    scene.debug:line(vec3(0.1, 0.6, 0.1-1),vec3(0.1, 0.6, 0.1+1),color(47, 239, 5))
    scene.debug:line(vec3(1.5, 0.3, 0.5-1),vec3(1.5, 0.3, 0.5+1),color(47, 239, 5))
    scene.debug:line(vec3(2.5, 0.3, 0.5-1),vec3(2.5, 0.3, 0.5+1),color(47, 239, 5))
end

function Chest:interact()
    if not self.open then        
        self.open = true
        tween(1.6, self, {angle = 90, y=10}, {easing=tween.easing.backOut,loop = tween.loop.once })
    else
        self.open = false
        tween(1.6, self, {angle = 0, y=0.6}, tween.easing.cubicIn)
    end
end

function Chest:touched(touch)
    if touch.state == BEGAN then
        self:interact()
    end
end
Tagged:

Comments

  • Posts: 1,629

    I’m not sure if this will help but for my helicopter project I put all the helicopter models inside a parent entity. Then I can rotate the parent entity, and offset the models however I like using their own position settings.

  • edited January 2 Posts: 190

    @UberGoober Thank you for reminding me. I almost forgot the entity.parent. I added a few changes and now the effect is as follows:

    https://youtu.be/xXZojXXQXW0

  • edited January 2 Posts: 190

    The changed code:

    Chest = class()
    
    function Chest:init()
        e = self.entity
        self.base = scene:entity()
        self.base.parent = e
        self.base.position = vec3(0.5, 0.3, 0.5)
        local r1 = self.base:add(craft.renderer, craft.model.cube(vec3(0.8,0.6,0.8)))
        r1.material = craft.material(asset.builtin.Materials.Specular)
        r1.material.diffuse = color(133, 79, 30)
    
        self.root = scene:entity()
        self.root.position = vec3(1.5, 0.3, 0.5)
        local r0 = self.root:add(craft.renderer, craft.model.cube(vec3(0.8,0.2,0.8),vec3(0.3,0.1,0.4)))
    
        self.top = scene:entity()
        self.top.parent = self.root
        self.top.position = vec3(0.1, 0.6, 0.1)
        local r2 = self.top:add(craft.renderer, craft.model.cube(vec3(0.8,0.2,0.8),vec3(0.4,0.1,0.4)))
        r2.material = craft.material(asset.builtin.Materials.Specular)
        r2.material.diffuse = color(66, 47, 30, 255)
        self.angle = 0
        self.y = 0.6
    
        self.ball = scene:entity()
        self.ball.parent = self.root
        self.ball.position = vec3(0, 0.3, 0.5)
        local r3 = self.ball:add(craft.renderer, craft.model.icosphere(0.2))
        r3.material = craft.material(asset.builtin.Materials.Specular)
        r3.material.diffuse = color(133, 124, 30)
    
        self.obj = scene:entity()
        self.obj.parent = self.root
        self.obj.position = vec3(1.5, 0.3, 0.5)
        self.obj.scale = vec3(0.5, 0.5, 0.5)
        local r4 = self.obj:add(craft.renderer, craft.model(asset.builtin.Primitives.RoundedCube))
        r4.material = craft.material(asset.builtin.Materials.Specular)
        r4.material.diffuse = color(30, 133, 101)
    
        self.floor = scene:entity()
        self.floor.parent = e
        self.floor.position = vec3(0.1, 0.6, 0.1)
        local r5 = self.floor:add(craft.renderer, craft.model.plane(vec2(1.2,1.2),vec3(0.6,0.0,0.6)))
        r5.material = craft.material(asset.builtin.Materials.Specular)
        r5.material.diffuse = color(46, 66, 30)
    
        touches.addHandler(self, -1, false)
    end
    
    function Chest:update()
        self.root.rotation = quat.eulerAngles(0,  0, self.angle)
        self.top.rotation = quat.eulerAngles(0,  0, self.angle*8)
        self.ball.rotation = quat.eulerAngles(0,  0, self.angle)
        self.obj.rotation = quat.eulerAngles(0,  0, self.angle*10)
        self.floor.rotation = quat.eulerAngles(0,  0, self.angle)
    
        scene.debug:line(vec3(0.1, 0.6, 0.1-1),vec3(0.1, 0.6, 0.1+1),color(47, 239, 5))
        scene.debug:line(vec3(1.5, 0.3, 0.5-1),vec3(1.5, 0.3, 0.5+1),color(239, 5, 5))
    
        local a = self.ball.worldPosition + vec3(0,0,-1)
        local b = self.ball.worldPosition + vec3(0,0,1)
        scene.debug:line(a, b,color(239, 5, 199))
    
        local a = self.top.worldPosition + vec3(0,0,-1)
        local b = self.top.worldPosition + vec3(0,0,1)
        scene.debug:line(a, b,color(16, 239, 5))
    
        local a = self.obj.worldPosition + vec3(0,0,-1)
        local b = self.obj.worldPosition + vec3(0,0,1)
        scene.debug:line(a, b,color(239, 233, 5))
    end
    
    
    function Chest:interact()
        if not self.open then
            self.open = true
            tween(1.6, self, {angle = 90, y=10}, {easing=tween.easing.backOut,loop = tween.loop.once })
        else
            self.open = false
            tween(1.6, self, {angle = 0, y=0.6}, tween.easing.cubicIn)
        end
    end
    
    
    function Chest:touched(touch)
        if touch.state == BEGAN then
            self:interact()
        end
    end
    
    
  • Posts: 190

    The problem now is that objects with the offset attribute can easily rotate around different axes by performing their own rotate method, objects that don’t have the offset property are limited to a certain extent, and their own rotate method can only rotate around their central axis, and objects that want to rotate around an axis in another location can only do so by following these steps:

    1. Add a parent entity to the object;
    2. Set the parent entity ’s position (that is, the Axis around which the object will rotate) ;
    3. Rotate the parent entity, the object is then rotated.
  • Posts: 190

    @John Can all types of models (cube,plane,icosphere,loaded model etc.) have an offset property, and not just the cube and the plane, so they can all deal with rotation in a consistent way, thanks

Sign In or Register to comment.