@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?
@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
@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.
@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.
@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.
@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.
@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
@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.
@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?
@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
@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.
@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
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.
@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.
@piinthesky That seems to work, but you’re constantly creating the ov table in the touched function as you’re moving your finger.
@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
@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.
@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?
@Bri_G Can you give the exact name of the discussion. I’m not finding it and the code doesn’t sound familiar.
@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.