Howdy, Stranger!

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

cameras and scenes?

@John @Simeon i would like to have two scenes that i can switch between, each one having an independent OrbitViewer. I was able to make this partially work but unfortunately if i move the camera in the first scene it is also moved in the second scene. Is it possible to have two cameras/orbitViewers with independent locations or do i have to memorise the camera position for each scene and refined the starting position of the single camera at each scene switch?

Tagged:

Comments

  • dave1707dave1707 Mod
    Posts: 7,155

    @piinthesky Is this close to what you’re looking for.

    function setup()
        parameter.boolean("red",true)
        fill(255)
        assert(craft, "Please include Craft as a dependency")
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")   
    
        scene1 = craft.scene()    
        v1=scene1.camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 1000)
        createSphere1(scene1,vec3(-15,0,0),255,0,0)
    
        scene2 = craft.scene()    
        v2=scene2.camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 1000)
        createSphere1(scene2,vec3(15,0,0),0,255,0)
    end
    
    function draw()
        update(DeltaTime)
        text("Slide you finger to move balls.",WIDTH/2,HEIGHT-50)
        text("Move slider to switch scenes.",WIDTH/2,HEIGHT-100)
    end
    
    function update(dt)
        if red then
            scene1:update(dt)
            scene1:draw()
        else
            scene2:update(dt)
            scene2:draw()
        end
    end
    
    function touched(t)
        if t.state==MOVING then
            if red then
                v1.rx=v1.rx+1
                v1.ry=v1.ry+1
            else
                v2.rx=v2.rx+2
                v2.ry=v2.ry+2
            end
        end
    end
    
    function createSphere1(sc,p,r,g,b)
        local pt=sc:entity()
        pt.position=vec3(p.x,p.y,p.z)
        pt.model = craft.model.icosphere(2,2)
        pt.material = craft.material("Materials:Specular")
        pt.material.diffuse=color(r,g,b)
    end
    
  • Posts: 337

    @dave1707 that is what essentially i am doing currently. i don’t see why you need your touches function as the orbitviewer handles the touches itself. if i comment out your touches function, then only the scene2 viewer reacts to touches.

  • dave1707dave1707 Mod
    Posts: 7,155

    @piinthesky That’s why I added my own touched function. The 2 scenes can be seperated whereas using the OrbitViewer touched function doesn’t seperate them. The OrbitViewer touched function uses the last scene it was added to.

  • Posts: 337

    @dave1707 yes that’s the issue. The touch handler in the orbitviewer is not unique to each scene-not sure how to fix that in an elegant way.

  • Posts: 1,014

    @piinthesky - have you tried having two cameras defined which stay at the same relative offset to each other. I thought about that for use in a 3D application. I’m sure Ignatz did that with his spitfire project with a camera view from inside the cockpit and one to the rear. In fact it’s one camera with an offset when you need to switch views.

  • dave1707dave1707 Mod
    edited December 5 Posts: 7,155

    @piinthesky Not sure what you’re exactly after, here’s another example of 2 different scenes. I altered code from my starter game 22 code to create this. Tap screen to start, tilt screen to turn and slide the parameter slider to change screen. A lot of different scenes could be created, I would do it different though.

    function setup() 
        parameter.boolean("xxx",true)
        assert(craft, "Please include Craft as a dependency")
    
        hgx1,hgx2=Gravity.x,Gravity.x
        speed1,speed2=0,0
        ey1,ey2,ang1,ang2=45,45,0,0
        cameraX1,cameraZ1,cameraX2,cameraZ2=-205,-205,-205,-205
    
        scene1 = craft.scene()
        scene1.camera.position = vec3(cameraX,0,cameraZ)
        scene1.sun.rotation = quat.eulerAngles(45,0,45)
        scene1.ambientColor = color(90,90,90)
        skyMaterial1 = scene1.sky.material
        skyMaterial1.horizon = color(0, 203, 255, 255)    
    
        scene2 = craft.scene()
        scene2.camera.position = vec3(cameraX,0,cameraZ)
        scene2.sun.rotation = quat.eulerAngles(45,0,45)
        scene2.ambientColor = color(90,90,90)
        skyMaterial2 = scene2.sky.material
        skyMaterial2.horizon = color(255, 0, 162, 255)    
    
        createFloor1() 
        createFloor2() 
    
        for z=1,100 do 
            createSphere1(math.random(-200,200),math.random(-200,200))
            createSphere2(math.random(-200,200),math.random(-200,200))
        end
    end
    
    function update(dt)
        if xxx then
            speed2=0
            scene1:update(dt)
            scene1.camera.position = vec3(cameraX1,1,cameraZ1)
            scene1.camera.eulerAngles=vec3(0,ey1,0)
        else
            scene2:update(dt)
            speed1=0
            scene2.camera.position = vec3(cameraX2,1,cameraZ2)
            scene2.camera.eulerAngles=vec3(0,ey2,0)
        end
    end
    
    function draw()
        background(0)
        fill(255)
        update(DeltaTime)
        if xxx then
            scene1:draw() 
            if speed1==0 then
                text("Tap screen to start",WIDTH/2,HEIGHT-30)
            end
        else
            scene2:draw()  
            if speed2==0 then
                text("Tap screen to start",WIDTH/2,HEIGHT-30)
            end
        end
        updateCameraPos()        
        checkTilt()  
        drawShip()
    end
    
    function touched(t)
        if t.state==BEGAN then
            if xxx then
                ang1=0
                speed1=.5
            else
                ang2=0
                speed2=.5
            end
        end
    end
    
    function updateCameraPos()
        if xxx then
            ey1=ey1-ang1
            x1=speed1*math.sin(math.rad(ey1))
            z1=speed1*math.cos(math.rad(ey1)) 
            cameraX1=cameraX1+x1
            cameraZ1=cameraZ1+z1
        else
            ey2=ey2-ang2
            x2=speed2*math.sin(math.rad(ey2))
            z2=speed2*math.cos(math.rad(ey2)) 
            cameraX2=cameraX2+x2
            cameraZ2=cameraZ2+z2
        end
    end
    
    function checkTilt()
        if xxx then
            gx1=Gravity.x
            ang1=ang1+(gx1-hgx1)*4
            hgx1=gx1
            if gx1>-.001 and gx1<.001 then
                ang1=0
            end
        else
            gx2=Gravity.x
            ang2=ang2+(gx2-hgx2)*4
            hgx2=gx2
            if gx2>-.001 and gx2<.001 then
                ang2=0
            end
        end
    end
    
    function drawShip()
        pushMatrix()
        if xxx then
            translate(WIDTH/2,HEIGHT/2-100)
            rotate(ang1*-30)
            sprite("Tyrian Remastered:Boss A",0,0,300)    translate()
        else
            translate(WIDTH/2,HEIGHT/2-100)
            rotate(ang2*-30)
            sprite("Tyrian Remastered:Boss B",0,0,200)    translate()
        end
        popMatrix()
    end
    
    function createFloor1(x,z)
        c1=scene1:entity()
        c1.model = craft.model.cube(vec3(400,1,400))
        c1.position=vec3(x,-.5,z)
        c1.material = craft.material("Materials:Standard")
        c1.material.map = readImage("Surfaces:Desert Cliff Color")
        c1.material.offsetRepeat=vec4(0,0,50,50)
    end
    
    function createFloor2(x,z)
        c1=scene2:entity()
        c1.model = craft.model.cube(vec3(400,1,400))
        c1.position=vec3(x,-.5,z)
        c1.material = craft.material("Materials:Standard")
        c1.material.map = readImage("Surfaces:Desert Cliff Normal")
        c1.material.offsetRepeat=vec4(0,0,50,50)
    end
    
    function createSphere1(x,z)
        sphere1=scene1:entity()
        sphere1.model = craft.model.icosphere(2,1)
        sphere1.position=vec3(x,1,z)
        sphere1.material = craft.material("Materials:Specular")
        sphere1.material.diffuse=color(255,0,0)
    end
    
    function createSphere2(x,z)
        sphere1=scene2:entity()
        sphere1.model = craft.model.icosphere(2,1)
        sphere1.position=vec3(x,1,z)
        sphere1.material = craft.material("Materials:Specular")
        sphere1.material.diffuse=color(0,255,0)
    end
    
  • Posts: 337

    @dave1707 @Bri_G i was hoping to ‘elegantly’ use the orbitviewer and the touches handler to treat independently the camera positioning, panning and zooming etc. for the multiple scene case, rather than having to reinvent the wheel.

  • edited December 6 Posts: 337

    @John, i think dave1707’s first example above ‘fails’ because the touch is captured by scene1 and never gets to scene2. How does one implement shared touches with touchhandler? there is some code for shared touches but it does not seem to be available as an option?

  • Posts: 337

    @dave1707 this seems to work.....

    function setup()
        parameter.boolean("red",true)
        fill(255)
        assert(craft, "Please include Craft as a dependency")
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")   
    
        scene1 = craft.scene()    
        scene1.camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 1000)
        createSphere1(scene1,vec3(-15,0,0),255,0,0)
    
        scene2 = craft.scene()    
        scene2.camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 1000)
        createSphere1(scene2,vec3(15,0,0),0,255,0)
    
    end
    
    function draw()
        update(DeltaTime)
        text("Slide you finger to move balls.",WIDTH/2,HEIGHT-50)
        text("Move slider to switch scenes.",WIDTH/2,HEIGHT-100)
    end
    
    function update(dt)
        if red then
            scene1:update(dt)
            scene1:draw()
        else
            scene2:update(dt)
            scene2:draw()
        end
    end
    
    function touched(touch)
        if red then
           touches.handlers[1]:touched(touch)
        else
           touches.handlers[2]:touched(touch)
        end
    end
    
    function createSphere1(sc,p,r,g,b)
        local pt=sc:entity()
        pt.position=vec3(p.x,p.y,p.z)
        pt.model = craft.model.icosphere(2,2)
        pt.material = craft.material("Materials:Specular")
        pt.material.diffuse=color(r,g,b)
    end
    
  • dave1707dave1707 Mod
    Posts: 7,155

    @piinthesky That sure does work a lot better. Thanks for sharing. I’ll have to keep a copy of that for reference. I wonder how many other things there are that we don’t know about.

  • dave1707dave1707 Mod
    Posts: 7,155

    @piinthesky I tried creating more scenes, but they don’t seem to work. Change the for loop value so you create different number of scenes. If the number of scenes are 1,2, or 3 they all seem to work OK. If you create 4 or 5 scenes, then only the first and last scenes work OK. Don’t know if it’s my code or the touch handler that not working right.

    function setup()
        assert(craft, "Please include Craft as a dependency")
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")  
    
        col={color(255,0,0),color(0,255,0),color(0,0,255),
                color(255,255,0),color(0,255,255)}
    
        parameter.integer("val",1,#col)
    
        sc={}   -- scene table
    
        for z=1,5 do    -- change this to create 1 then 2 then 3,4,5 scenes
            sc[z]=craft.scene()    
            sc[z].camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 1000)
            createSphere1(sc[z],vec3(-15,0,0),col[z])
        end
    end
    
    function draw()
        update(DeltaTime)
        fill(255)
        text("Scene  "..val,WIDTH/2,HEIGHT-50)
    end
    
    function update(dt)
        sc[val]:update(dt)
        sc[val]:draw()
    end
    
    function touched(touch)
        touches.handlers[val]:touched(touch)
    end
    
    function createSphere1(sc,pos,col)
        local pt=sc:entity()
        pt.position=pos
        pt.model = craft.model.icosphere(2,2)
        pt.material = craft.material("Materials:Specular")
        pt.material.diffuse=col
    end
    
  • JohnJohn Admin Mod
    Posts: 522

    Hi guys, the whole Camera library and Touches library were never really meant to be used for multiple scenes. It's probably better to just copy those projects into your project and then modify them as you see fit to fix any issues like this. Calling things manually like @dave1707 is doing is probably the best option.

  • edited December 7 Posts: 337

    @dave1707, another try! this might be the correct way to do it (nice to find a way reuse @John ‘s code)

    — scenetest2
    function setup()
        assert(craft, "Please include Craft as a dependency")
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")  
    
        col={color(255,0,0),color(0,255,0),color(0,0,255),
                color(255,255,0),color(0,255,255)}
    
        parameter.integer("val",1,#col)
    
        sc={}   -- scene table
    
        for z=1,5 do    -- change this to create 1 then 2 then 3,4,5 scenes
            sc[z]=craft.scene()    
            sc[z].camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 1000)
            createSphere1(sc[z],vec3(-15,0,0),col[z])
        end
    end
    
    function draw()
        update(DeltaTime)
        fill(255)
        text("Scene  "..val,WIDTH/2,HEIGHT-50)
    end
    
    function update(dt)
        sc[val]:update(dt)
        sc[val]:draw()
    end
    
    function touched(touch)
        ov=sc[val].camera:get(OrbitViewer)
        ov:touched(touch)
    end
    
    function createSphere1(sc,pos,col)
        local pt=sc:entity()
        pt.position=pos
        pt.model = craft.model.icosphere(2,2)
        pt.material = craft.material("Materials:Specular")
        pt.material.diffuse=col
    end
    

    note that the touch.handler is not necessary if there is an explicit touch function call in the main code. in fact in that case the touch.handler call in the orbitviewer.init can also be removed.

  • dave1707dave1707 Mod
    Posts: 7,155

    @piinthesky That seems to work, but you’re constantly creating the ov table in the touched function as you’re moving your finger.

  • Posts: 337

    @dave1707 third time lucky!?

    -- scenetest2
    function setup()
        assert(craft, "Please include Craft as a dependency")
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")  
    
        col={color(255,0,0),color(0,255,0),color(0,0,255),
                color(255,255,0),color(0,255,255)}
    
        parameter.integer("val",1,#col)
    
        sc={}   -- scene table
        ov={}
        for z=1,5 do    -- change this to create 1 then 2 then 3,4,5 scenes
            sc[z]=craft.scene()    
            sc[z].camera:add(OrbitViewer, vec3(0,0,0), 100, 0, 1000)
            createSphere1(sc[z],vec3(-15,0,0),col[z])
            ov[z]=sc[z].camera:get(OrbitViewer)
        end
    end
    
    function draw()
        update(DeltaTime)
        fill(255)
        text("Scene  "..val,WIDTH/2,HEIGHT-50)
    end
    
    function update(dt)
        sc[val]:update(dt)
        sc[val]:draw()
    end
    
    function touched(touch)
        ov[val]:touched(touch)
    end
    
    function createSphere1(sc,pos,col)
        local pt=sc:entity()
        pt.position=pos
        pt.model = craft.model.icosphere(2,2)
        pt.material = craft.material("Materials:Specular")
        pt.material.diffuse=col
    end
    
  • dave1707dave1707 Mod
    Posts: 7,155

    @piinthesky Good job, that one looks OK. Since the touched function is in this code, the Touches dependency doesn’t have to be checked in Cameras. But it still needs to be checked for the other projects that use OrbitViewer.

  • edited December 7 Posts: 1,014

    @dave1707 - hi, just revisited some old code you provided when I was having trouble with viewers. It was in the a thread about 3D model viewing, and was the final code sample in the thread. You set up a cube of spheres with a line of spheres internally and a further sphere outside the cube. The code allowed you to rotate the camera around the models by changing the viewer x,y and z values.

    I thought I'd revisit it after reading this thread and ran into a problem - probably my misinterpretation of the code or the conventions used in the 3D Codea universe. The problem is - when I change values in the X axis the models rotate on the Y axis and vice versa. The Z axis just acts like the expected zoom.

    I have heard of some conventions exchanging the Y axis with the Z axis, is that the case here?

  • dave1707dave1707 Mod
    Posts: 7,155

    @Bri_G Can you give the exact name of the discussion. I’m not finding it and the code doesn’t sound familiar.

  • dave1707dave1707 Mod
    Posts: 7,155

    @Bri_G I found it, I just didn’t go far enough back. My understanding of the axis is the X axis goes left and right. The Y axis is up and down and the Z axis is forward and backward. When I adjust the sliders, the image rotated on the correct axis.

  • dave1707dave1707 Mod
    edited December 8 Posts: 7,155

    @Bri_G Here’s another demo. The red line is the x axis. Green is the y axis and blue is the z axis.

    function setup()
        parameter.integer("x",-90,90,10)
        parameter.integer("y",-90,90,5)
        parameter.number("z",0,200,200)
        assert(craft, "Please include Craft as a dependency")
        assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")        
        scene = craft.scene()
        v=scene.camera:add(OrbitViewer, vec3(0,0,0), 450, 0, 1000)
        createPlane()
    end
    
    function draw()
        update(DeltaTime)
        scene:draw()
    end
    
    function update(dt)
        scene:update(dt)
        v.rx=x
        v.ry=y
        v.zoom=z
    end
    
    function createPlane()
        local pt=scene:entity()
        pt.model = craft.model.cube(vec3(2000,1,1))
        pt.material = craft.material("Materials:Specular")
        pt.material.diffuse=color(255,0,0)
    
        local pt=scene:entity()
        pt.model = craft.model.cube(vec3(1,2000,1))
        pt.material = craft.material("Materials:Specular")
        pt.material.diffuse=color(0,255,0)
    
        local pt=scene:entity()
        pt.model = craft.model.cube(vec3(1,1,2000))
        pt.material = craft.material("Materials:Specular")
        pt.material.diffuse=color(0,0,255)
    end
    
  • Posts: 1,014

    @dave1707 - thanks for that, I was misinterpreting the way the system works. I thought that changing the x value would affect the y an z axes, not the rotation around the x axis. But there is something wrong with your demo. Rotate around any axis and the other two axes should both move,. The z adjustment is not in the update. I put it in but it still isn’t working properly.

  • dave1707dave1707 Mod
    Posts: 7,155

    @Bri_G I changed the range of the sliders from -30,30 to -120,120 and the camera position closer to the center. That should show the rotation more. As for the Z axis, that’s just zooming in and out and can be done using the 2 finger squeeze and spread.

  • dave1707dave1707 Mod
    Posts: 7,155

    @Bri_G I modified the above code to allow zooming in/out using the z slider. I also corrected an error I had with the red x axis. It was originally 2000,1,0 and it should have been 2000,1,1. I don’t think the OrbitViewer rotates around the z axis like the x and y does, but just zooms in or out.

  • edited December 8 Posts: 1,014

    @dave1707 - modified your code a little, what you say is correct the v.rx and v.ry do rotate around the x an y axes respectively in degrees. The v.rz is not accessible as I think @John has used it as you describe - a zoom function.

    I think I can use the viewer as is to achieve what I need. Hopefully I’ll post something soon to describe what I find. Thanks for your help.


    -- ViewerRotate displayMode(OVERLAY) function setup() parameter.integer("x",-179,179,10) parameter.integer("y",-179,179,10) parameter.integer("z",-179,179,10) assert(craft, "Please include Craft as a dependency") assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency") scene = craft.scene() v=scene.camera:add(OrbitViewer, vec3(0,0,0), 450, 0, 1000) createPlane() end function draw() update(DeltaTime) scene:draw() end function update(dt) scene:update(dt) v.rx=x v.ry=y v.rz=z end function createPlane() local pt=scene:entity() pt.model = craft.model.cube(vec3(200,2,2)) pt.material = craft.material("Materials:Specular") pt.material.diffuse=color(255,0,0) local pt=scene:entity() pt.model = craft.model.cube(vec3(2,200,2)) pt.material = craft.material("Materials:Specular") pt.material.diffuse=color(0,255,0) local pt=scene:entity() pt.model = craft.model.cube(vec3(2,2,200)) pt.material = craft.material("Materials:Specular") pt.material.diffuse=color(0,0,255) end
Sign In or Register to comment.