Yes, Klaus wrote in another thread its totally possible with custom code.
Only i dont have much time now for developing it.
Check Brink traveler in Quest2 or the free Bigscreen app is also use snap turning if i remember correctly.
So it's not a smooth rotating, which gives nausea in VR, instead a fixed value, say 30 or 45 degre..
Instant turning or very quick (say 0.1-0.3sec)
Oh, you can choose this method in Walkabout minigolf too!
Virtual Gallery (template)
-
-
I haven't done anything in the 3D department yet so please allow me a rookie question:
Can I implement gigapixel panoramas as images in the gallery?
So can I take a template like this and put really large images onto the wall which are deep zoomable very far?
Thanks!
-
Here is a modified version of depthmap_navigation.xml that will allow for fixed degree rotation. By default, it is off and has the same behaviour as the original depthmap_navigation.
To enable the fixed rotation, use these parameters (include this in your tour.xml):
I had to mess around with the degrees values a lot so not sure how they translate to your headset.
I'm not sure how to include this in my Virtual Gallery without breaking copyright.
Code
Display More<krpano> <!-- depthmap_navigation.xml krpano 1.21 https://krpano.com/plugins/xmlextensions/#depthmap_navigation Depthmap Navigation Controls - Arrow-keys or WASD-keys or Middle/Right-Mousebutton Navigation on Desktop - On-Screen-Touchpad for Mobile Devices - VR-Controller Joystick/Touchpad support for WebVR - Optional Depthmap/3D-Model Hit/Collision-Detection Keyboard Keys: - Arrow/WASD for forward/backward/left/right moving - holding SHIFT for faster movement - Q for moving up - Y or Z for moving down - F for toggling between walking and flying Mouse: - Left-Mousebutton: normal looking around / rotating - Left+SHIFT or Middle- and Right-Mousebutton: moving around - Holding the ALT, CTRL or SHIFT-key: moving up and down - In Dollhouse-mode the moving around/up-down controls are swapped Settings: - movemode = "walking" or "flying" - speed = movement speed - friction = movement friction - collision = true or false, collision-detection / stop on walls - collision_stopdistance = keep this distance in cm to walls/surfaces - collision_moveback = when hitting a wall, move back x times - collision_bounceback = when hitting a wall, add a bounce movement --> <depthmap_navigation movemode="walking" speed.number="0.5" friction.number="0.9" collision.bool="true" collision_stopdistance.number="30" collision_moveback.number="1.2" collision_bounceback.number="1.6" /> <!-- remove the default keyboard controls --> <control keycodesleft="" keycodesright="" keycodesup="" keycodesdown="" /> <!-- keyboard keycodes --> <keyb up="38" down="40" left="37" right="39" w="87" a="65" s="83" d="68" q="81" y="89" z="90" f="70" shift="16" ctrl="17" space="32" pageup="33" pagedown="34" /> <!-- state variables for walking/flying around in the depthmap/3d-model pano --> <walkaround forward="0" backward="0" left="0" right="0" up="0" down="0" faster="0" /> <joystick fixed="false" degrees="45" /> <!-- keyboard event handling --> <events name="depthmap_navigation" keep="true" onkeydown="depthmap_handlekey(1);" onkeyup="depthmap_handlekey(0);" /> <action name="depthmap_handlekey" args="keypressed" scope="local"> if( keycode == keyb.up OR keycode == keyb.w, copy(walkaround.forward, keypressed); , keycode == keyb.down OR keycode == keyb.s, copy(walkaround.backward, keypressed); , keycode == keyb.left OR keycode == keyb.a, copy(walkaround.left, keypressed); , keycode == keyb.right OR keycode == keyb.d, copy(walkaround.right, keypressed); , keycode == keyb.shift, copy(walkaround.faster, keypressed); , keycode == keyb.f AND keypressed == 0, switch(depthmap_navigation.movemode, 'walking', 'flying'); , keycode == keyb.q, copy(walkaround.up, keypressed); , keycode == keyb.y OR keycode == keyb.z, copy(walkaround.down, keypressed); ); </action> <!-- walking/flying controls --> <action name="depthmap_walkaroundmovement" autorun="onstart" type="Javascript"><![CDATA[ var mouse = krpano.mouse; var view = krpano.view; var dir = view.dir; var depthmap_navigation = krpano.depthmap_navigation var walkaround = krpano.walkaround; var vx=0, vy=0, vz=0; var rx=0; var touchpad_last_axis = [[0,0],[0,0]]; var touchpad_move_speed = 5.0; var touchpad_rotate_speed = 1.5; var joystick_move_speed = 1.0; var joystick_rotate_speed = 1.0; var blnAllowRotate = true; krpano.actions.renderloop( function() { var webvr = krpano.webvr; var friction = depthmap_navigation.friction; var acceleration = 1.0; // adjust the friction and acceleration depending on the framerate if (krpano.display.getAdaptiveFrictions) { var adjustedmovment = krpano.display.getAdaptiveFrictions(friction, acceleration/friction); friction = adjustedmovment.friction; acceleration = adjustedmovment.accel * friction; } vx *= friction; vy *= friction; vz *= friction; rx *= friction; if (vx*vx + vy*vy + vz*vz < 0.001) vx = vy = vz = 0; if (rx*rx < 0.01) rx = 0; var h = view.hlookat * Math.PI / 180.0; var v = view.vlookat * Math.PI / 180.0; // 2D direction vector (walking) var lx2 = Math.sin(h); var lz2 = Math.cos(h); // 3D direction vector (flying) var lx3 = dir.x; var ly3 = dir.y; var lz3 = dir.z; var wx = walkaround.right - walkaround.left; var wz = walkaround.forward - walkaround.backward; var wy = walkaround.up - walkaround.down; // handle the touchpad or joystick input from the vr-controllers var vrcontroller = (webvr && webvr.enabled) ? webvr.vrcontroller : null; if (vrcontroller) { var vrcontroller_count = vrcontroller.length; for (var i=0; i < vrcontroller_count; i++) { var controller = vrcontroller[i]; var axes = controller.axes; if (axes) { // when having a depthmap: move around (1), otherwise only rotate the pano (0) var controlmode = (krpano.display.havedepthmap || krpano.display.depthbuffer) ? 1 : 0; // when having two controllers use the touchpad/joystick from the right one only for rotating if (vrcontroller_count == 2 && controller.hand == "right") controlmode = 0; // joystick or touchpad? var y_axis_scale = +1.3; var is_touchpad = false; if (controller.id == "Daydream Controller" || controller.id == "Oculus Go Controller") { is_touchpad = true; } else if(controller.id == "OpenVR Gamepad") // HTC Vive Controller { is_touchpad = true; y_axis_scale *= -1.0; } if (webvr && webvr.iswebxr) { // WebXR: axes[0,1] = touchpad, axes[2,3] = thumbstick if ( axes[0] != 0 || axes[1] != 0 ) { is_touchpad = true; } else { // thumbstick - map axes for further processing axes = [axes[2],axes[3]]; } } if (is_touchpad) { // special touchpad control (swiping like) if (axes[0] != 0 && axes[1] != 0) { var dx = +(axes[0] - touchpad_last_axis[i][0]); var dz = -(axes[1] - touchpad_last_axis[i][1]) * y_axis_scale; touchpad_last_axis[i][0] = axes[0]; touchpad_last_axis[i][1] = axes[1]; if (Math.abs(dx) > 0.3) dx = 0; // too fast changes are probably no swipes if (Math.abs(dz) > 0.3) dz = 0; if (controlmode == 0) // rotate { rx += touchpad_rotate_speed * dx * acceleration; } else // move { vx += touchpad_move_speed * ( dx*lz2 + dz*lx2) * acceleration; vz += touchpad_move_speed * (-dx*lx2 + dz*lz2) * acceleration; } } } else { // joystick - direct control if (controlmode == 0) // rotate { if (krpano.joystick.fixed == "true") { if (Math.abs(axes[0]) > 0.2 && blnAllowRotate) { if (axes[0] < 0) rx = -krpano.joystick.degrees/45*Math.PI; else rx = krpano.joystick.degrees/45*Math.PI; blnAllowRotate = false; } if (Math.abs(axes[0]) < 0.2 && !blnAllowRotate) { blnAllowRotate = true; } } else { if (Math.abs(axes[0]) > 0.2) { rx = joystick_rotate_speed * axes[0]; } } } else // move { // ignore too small values, some vr-controllers, e.g. Windows MR ones, are constantly reporting small wrong values if ( Math.abs(axes[0]) > 0.2 ) wx += joystick_move_speed * axes[0]; if ( Math.abs(axes[1]) > 0.2 ) wz -= joystick_move_speed * axes[1]; } } } } } var wl = Math.sqrt(wx*wx + wz*wz); if (wl > 0) { // normalize the moving speed wl = acceleration * depthmap_navigation.speed / wl; if (walkaround.faster > 0) wl *= 3; wx *= wl; wz *= wl; if (wx) { vx += wx*lz2; vz -= wx*lx2; } if (wz) { if (depthmap_navigation.movemode == "flying") { vx += wz*lx3; vz += wz*lz3; vy += wz*ly3; } else { vx += wz*lx2; vz += wz*lz2; } } } if (wy) { vy -= 0.5 * acceleration * depthmap_navigation.speed * wy; } if ((mouse.leftbutton && mouse.shiftkey) || mouse.middlebutton || mouse.rightbutton) { var is_dollhouse_view = (view.oz > 100); var extrakey = mouse.ctrlkey | mouse.altkey; var dragspeed = (is_dollhouse_view ? 0.1 : 0.05) * acceleration; var dx = -dragspeed * mouse.dx; var dy = (extrakey ^ is_dollhouse_view) ? +dragspeed * mouse.dy : 0; var dz = (extrakey ^ is_dollhouse_view) ? 0 : +dragspeed * mouse.dy; vx += dx*dir.rx + dy*dir.ux + dz*dir.x; vy += dx*dir.ry + dy*dir.uy + dz*dir.y * (depthmap_navigation.movemode == "flying"); vz += dx*dir.rz + dy*dir.uz + dz*dir.z; } var vspeed = Math.sqrt(vx*vx + vy*vy + vz*vz); if (vspeed > 0) { // simple collision testing if (depthmap_navigation.collision && view.oz < 200) // do collision testing only in non-dollhouse-view { var hit = krpano.actions.raycastdepth(view.tx, view.ty, view.tz, vx, vy, vz); if (hit) { if (hit.d > 0 && hit.d < depthmap_navigation.collision_stopdistance) { // slide along walls var vlen = Math.sqrt(vx*vx + vy*vy + vz*vz); if (vlen > 0) { var pushback = -(depthmap_navigation.collision_stopdistance - hit.d) / vlen * depthmap_navigation.collision_moveback; view.tx += pushback * vx; view.ty += pushback * vy; view.tz += pushback * vz; var hitscale = (vx*hit.nx + vy*hit.ny + vz*hit.nz) * depthmap_navigation.collision_bounceback; vx -= hit.nx * hitscale; vy -= hit.ny * hitscale; vz -= hit.nz * hitscale; } } } } view.tx += vx; view.ty += vy; view.tz += vz; } if (rx != 0) { webvr.hlookatoffset += rx; //webvr.lookat = rx; } }); ]]></action> <!-- some buttons --> <style name="depthmap_button" type="text" css="text-align:center;" padding="4 8" bgborder="0 0xFFFFFF 1" bgroundedge="1" bgshadow="0 1 4 0x000000 1.0" ondown="set(bgcolor, 0xDDDDDD);" onup="set(bgcolor, 0xFFFFFF);" /> <style name="depthmap_info" type="text" css="color:#FFFFFF;text-align:center;" bg="false" txtshadow="0 1 4 0x000000 1.0" enabled="false" /> <layer name="moveup" keep="true" style="depthmap_button" html="▲" align="rightbottom" x="20" y="50" ondown="set(walkaround.up,1);" onup="set(walkaround.up,0);" /> <layer name="movedn" keep="true" style="depthmap_button" html="▼" align="rightbottom" x="20" y="20" ondown="set(walkaround.down,1);" onup="set(walkaround.down,0);" /> <!-- info texts --> <layer name="depthmap_walkinfo" keep="true" style="depthmap_info" align="center" y="+25%" html="Walk around using the[br]Keyboard Arrow- or W,A,S,D-keys" devices="desktop" /> <!-- drag area for touch devices --> <layer name="walkinfo_touch" keep="true" type="text" align="bottom" y="85" html="Hold down here[br]and drag around[br]for walking" bgalpha="0.3" devices="handheld" css="color:#FFFFFF;text-align:center;" txtshadow="0 1 4 0x000000 1.0" vcenter="true" width="140" height="140" bgroundedge="180" ondown="dragcontrol();" /> <events name="walkinfo_touch" keep="true" devices="mobile" onresize="if(stagewidth GT stageheight, set(layer[walkinfo_touch], align=rightbottom, x=80, y=40); , set(layer[walkinfo_touch], align=bottom, x=0, y=85); ); " /> <action name="dragcontrol" scope="local"> copy(mx,mouse.x); copy(my,mouse.y); tween(caller.alpha,0); asyncloop(caller.pressed, calc(walkaround.forward, (mouse.y - my) * -0.25); calc(walkaround.left, (mouse.x - mx) * -0.25); copy(mx, mouse.x); copy(my, mouse.y); , set(walkaround.left, 0); set(walkaround.forward, 0); tween(caller.alpha,1); ); </action> </krpano>
-
I also managed to disable the "ground floor clicking" when VR is enabled. Will release an update of all galleries so it includes all these changes.
-
Wow, many thanks for your work!
I tested, and fixed rotation work :)Moving speed is not controller by joystick_move_speed instead the main deptmap navigation "speed.number", right?
Is it normal?
Also, in many cases i like to use only one controller (the right), joy forward/backw = move (speed depend on the angle of joy), and joy left-right= fixed rotate.
I'm so excited :) -
Updated all templates to include modified depthmap_navigation. Also removed clicking the floor when in VR mode.
-
Updated all templates to include modified depthmap_navigation. Also removed clicking the floor when in VR mode.
Thanks for your work!
Can you mabe say something about my question above? Thanks!
-
I haven't done anything in the 3D department yet so please allow me a rookie question:
Can I implement gigapixel panoramas as images in the gallery?
So can I take a template like this and put really large images onto the wall which are deep zoomable very far?
Thanks!
I didnt answer because tbh, I have no idea. But I'm willing to test if you provide an image.
I can have a look at the gigapixel one and a resized one to see the difference...Or you can try yourself by downloading the templates
-
Is it possible to not just see regular 2D pictures in the gallery, but also load a full 360 photo?
When i finished watching that i can click on hotspot to go back to the gallery model and continue walking to next 2D OR 360 picture :) -
As an experiment, I added this in these templates:
https://krpano.com/forum/wbb/inde…&threadID=19148
https://krpano.com/forum/wbb/inde…&threadID=19206- pano support: if the image that is being clicked has a pano associated to it, the pano will be opened on click. Pano images should be in the /images/panos/ directory and have the same name as the image (image-1.jpg, image-2.jpg, ...). The pano must be in equirectangular format as krpano will try to load it as sphere.
So images in the gallery are like previews of the pano :) -
Now that was quick!
Thanks a lot, will test in these days. -
Participate now!
Don’t have an account yet? Register yourself now and be a part of our community!