About Monkey 2 › Forums › Monkey 2 Code Library › mojo3d-vr VR Samples
This topic contains 2 replies, has 1 voice, and was last updated by
DruggedBunny
1 year, 2 months ago.
-
AuthorPosts
-
February 10, 2018 at 3:17 pm #13602
Here’s a basic VR demo for use with the latest Patreon subscriber release (subscribe and drop Mark an email for access!*), or the Github build-it-yourself develop branch. The mojo3d-vr module is a simple wrapper around OpenVR.
* Note that Mark has only included this early version for playing with and doesn’t intend to focus on VR at this time, but it’s still a lot of fun to mess about with.
Should work with at least HTC Vive, Oculus Rift DK2 and CV1, with hand controller support for Vive and CV1.
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221[crayon-5cb9a3bd2315a220159918 inline="true" ]' Don't copy the 'crayon' line above if it's there -- forum bug!#Import "<std>"#Import "<mojo>"#Import "<mojo3d>"#Import "<mojo3d-vr>"Using std..Using mojo..Using mojo3d..Global AppName:String = "VR App"Class VRCamera Extends CameraField pivot:Model' Give Camera a parent pivot to allow free movement of' camera while including user's own head movements...Method New ()pivot = New ModelParent = pivotEnd' Update camera's own local matrix from VRRenderer's headset matrix...Method Update (renderer:VRRenderer)LocalBasis = renderer.HeadMatrix.mLocalPosition = renderer.HeadMatrix.tEndEndClass VRScene Extends Window' Core...Field scene:SceneField light:LightField renderer:VRRenderer ' VR renderer (duh)Field camera:VRCamera' Demo stuff...' Er, camera speed logic is a bit weird/unnecessary...Const CAMERA_SPEED_NORMAL:Float = 0.05 ' Normal camera movementConst CAMERA_SPEED_BOOST:Float = 4.0 ' Camera boost with Shift keyField cam_speed:Float = 1.0 ' Camera forward speedField headset:Model ' Used to give an in-scene shadow of user's head, not actually neededField test_cube:ModelMethod New (title:String, width:Int, height:Int, flags:WindowFlags)Super.New (title, width, height, flags)SeedRnd (Millisecs ())test_cube = Model.CreateBox (New Boxf (-0.5, -0.5, -0.5, 0.5, 0.5, 0.5), 1, 1, 1, New PbrMaterial (Color.Red))test_cube.Move (0, 0, 2)CreateScene (15)EndMethod CreateScene:Void (ground_size:Float = 100)' Create VR renderer and shadow resolution for close-up work,' with more numbers at the lower (closer) end of the range...renderer = New VRRenderer' VR renderer settings...renderer.TrackingSpace = VRTrackingSpace.Seated' Set up 3D scene stuff...scene = Scene.GetCurrent ()' Scene settings...scene.CSMSplits = New Float [] (2, 4, 16, 256)scene.AmbientLight = Color.White * 0.75scene.ClearColor = Color.Sky * 0.75' Light setup...light = New Lightlight.CastsShadow = Truelight.Range = 500light.Move (0, 20, 10)' Camera setup...camera = New VRCamera' Camera settings...camera.Near = 0.1' Headset cone model (just casts a shadow to show your head movement in-' scene). Not actually required...headset = Model.CreateCone (0.12, 0.12, Axis.Z, 8, New PbrMaterial (Color.Gold), camera)EndMethod UpdateGame ()' Reset default position...If Keyboard.KeyHit (Key.Enter)renderer.ResetSeatedPose ()Endif' Quit...If Keyboard.KeyHit (Key.Escape)App.Terminate ()Endif' Shadows on/off...If Keyboard.KeyHit (Key.S)light.CastsShadow = Not light.CastsShadowEndif' Speed booster...If Keyboard.KeyDown (Key.LeftShift)cam_speed = CAMERA_SPEED_BOOSTElsecam_speed = 1.0Endif' Forward...If Keyboard.KeyDown (Key.A)camera.pivot.Move (0.0, 0.0, CAMERA_SPEED_NORMAL * cam_speed)Endif' Back...If Keyboard.KeyDown (Key.Z)camera.pivot.Move (0.0, 0.0, -CAMERA_SPEED_NORMAL * cam_speed)Endif' Rotation...If Keyboard.KeyDown (Key.Left)camera.pivot.Rotate (0.0, 1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Right)camera.pivot.Rotate (0.0, -1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Up)camera.pivot.Rotate (1.0, 0.0, 0.0, True)EndifIf Keyboard.KeyDown (Key.Down)camera.pivot.Rotate (-1.0, 0.0, 0.0, True)EndifEnd' App window drawing (separate to VR headset output)...Method OnRender (canvas:Canvas) OverrideUpdateGame () ' Game-specific updatesRequestRender () ' Ask app window to redrawrenderer.Update () ' Update headset position, etccamera.Update (renderer) ' Update camera from renderer's headset matrixscene.Update () ' Update any physics, etc...scene.Render (canvas) ' Draw VR scene to canvas AND, automatically and separately, to headset' Some 2D drawing for the normal desktop window (ie. outside of VR headset)...' renderer:VRRenderer allows access to left/right views from headset. We use' the left view here for drawing in the standard window...canvas.DrawRect (0, Height, Width, -Height, renderer.LeftEyeImage)canvas.Scale (Width/App.ActiveWindow.Width, Height/App.ActiveWindow.Height)canvas.DrawText ("FPS: " + App.FPS, 0.0, 0.0)canvas.DrawText ("Camera controls: Cursors, plus A/Z (Shift for boost!)", 20.0, 20.0)EndEnd' All-in-one startup -- width and height relate to non-VR window; rendering is headset-native...Function RunVR (title:String, width:Int, height:Int, flags:WindowFlags = WindowFlags.Center)New AppInstanceNew VRScene (title, width, height, flags)App.Run ()EndFunction Main ()RunVR ("VR Scene", 640, 480, WindowFlags.Center)' RunVR ("VR Scene", 1920, 1080, WindowFlags.Fullscreen)EndFebruary 10, 2018 at 3:28 pm #13603This is a bigger demo, playing with physics.
We can’t currently render text in the headset — it doesn’t render to a canvas, just direct to headset, so we don’t have much control over that — so you’ll have to use the controls as shown in the main window. Awkward!
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520[crayon-5cb9a3bd2c69c887923317 inline="true" ]' Don't copy the 'crayon' line above if it's there -- forum bug!' TODO: Headbutt blocks doesn't collide, driving into them does...#Import "<std>"#Import "<mojo>"#Import "<mojo3d>"#Import "<mojo3d-vr>"#Import "<bullet>"Using std..Using mojo..Using mojo3d..Const WALL_WIDTH:Int = 15Const WALL_HEIGHT:Int = 10Const BULLET_FORCE:Float = 250.0 ' Too high will go through without colliding!Class VRCamera Extends CameraField pivot:Model' Give Camera a pivot to allow independent movement...Method New ()pivot = New ModelParent = pivotEnd' Update camera from VRRenderer's headset matrix...Method Update (renderer:VRRenderer)' LocalBasis = renderer.HeadMatrix.m' LocalPosition = renderer.HeadMatrix.tSetBasis (renderer.HeadMatrix.m, True)SetPosition (renderer.HeadMatrix.t, True)'Scene.Update ()EndEndClass PhysBoxPrivate' PhysParams is used internally to allow creation of box prior to manual placement.' Entities should not be manually positioned after being attached to a RigidBody.' Create PhysBox, manually position PhysBox.model, then call PhysBox.Start ().Class InitParamsField mass:FloatField group:ShortField mask:ShortField box:BoxfEnd' InitParams are only needed for setup, and freed afterwards, hence not added as separate fields.Field init:InitParamsPublic' Public references...Field model:Model ' mojo3d entityField collider:BoxCollider ' Bullet physics colliderField body:RigidBody ' Bullet physics bodyMethod New (width:Float = 1, height:Float = 1, depth:Float = 1, mass:Float = 1, material:Material = Null, parent:Entity = Null, group:Int = 1, mask:Int = 1)' Store setup params for PhysBox.Start ()init = New InitParamsinit.mass = massinit.group = groupinit.mask = maskinit.box = New Boxf (-width * 0.5, -height * 0.5, -depth * 0.5, width * 0.5, height * 0.5, depth * 0.5)If Not materialmaterial = New PbrMaterial (Color.Red)Endifmodel = Model.CreateBox (init.box, 1, 1, 1, material, parent)EndMethod Start (sleeps:Bool = True)collider = New BoxCollider (model)body = New RigidBody (model)collider.Box = init.boxbody.Mass = init.massbody.CollisionGroup = init.groupbody.CollisionMask = init.mask' body.Friction = 0' body.RollingFriction = 1.0body.Restitution = 0.1 ' Slight bounciness' Disables sleeping -- NOT generally desirable outside of demos, as most bodies should settle...' Recommended only for player-controlled bodies in general!If Not sleepsbody.btBody.setActivationState (bullet.DISABLE_DEACTIVATION)Endifinit = NullEndMethod Move (x:Float, y:Float, z:Float)model.Move (x, y, z)EndMethod Rotate (pitch:Float, roll:Float, yaw:Float, localspace:Bool = False)model.Rotate (pitch, roll, yaw, localspace)EndEndClass Entity Extension' Temp workaround for child-entity.PointAt by DoctorWhoof!' https://github.com/blitz-research/monkey2/issues/324Method WorldPointAt( target:Vec3f,up:Vec3f=New Vec3f( 0,1,0 ) )Local k:=(target-Position).Normalize()Local i:=up.Cross( k ).Normalize()Local j:=k.Cross( i )Basis=New Mat3f( i,j,k )End' Temp workaround for removing parent entities, by Mark:' http://monkeycoder.co.nz/forums/topic/mojo3d-set-to-default-parent/#post-12911Method RemoveParent ()Local matrix:AffineMat4f = MatrixParent = NullMatrix = matrixEndEnd' Main Game class...Class Game Extends Window' Er, camera speed logic is a bit weird/unnecessary...Const CAMERA_SPEED_NORMAL:Float = 0.05 ' Normal camera movementConst CAMERA_SPEED_BOOST:Float = 5.0 ' Camera boost with Shift keyField camera_speed:Float = 1.0 ' Camera forward speed' 3D scene references...Field scene:SceneField renderer:VRRendererField camera:VRCameraField light:LightField camera_collider:SphereColliderField camera_body:RigidBody' Physics box representing ground...Field ground:PhysBox' List of PhysBoxes...Field boxes:List <PhysBox>' App init/scene creation...Method New (title:String, width:Int, height:Int, flags:WindowFlags)Super.New (title, width, height, flags) ' Create windowSeedRnd (Millisecs ()) ' Init random seedSwapInterval = 1 ' V-sync onCreateScene (50) ' WAAAAAAAHHH! (Parameter = ground size.)EndMethod CreateScene:Void (ground_size:Float = 100)renderer = New VRRendererrenderer.TrackingSpace = VRTrackingSpace.Seated' Set up 3D scene stuff...scene = Scene.GetCurrent ()scene.CSMSplits = New Float [] (2, 4, 16, 256)ground = New PhysBox (ground_size, 1, ground_size, 0, New PbrMaterial (Color.Green * 0.25))camera = New VRCameralight = New Lightscene.AmbientLight = Color.White * 0.75scene.ClearColor = Color.Sky * 0.75' Camera setup...camera.FOV = 100camera.pivot.Move (0, 5, -10)camera.Near = 0.01camera.Far = 1000' Camera collision with boxes. Not with ground? Both masses = 0, possibly relevant...' NB. camera radius is half width of default block (1.0), minus a little to allow passing between columns of blocks...camera_collider = New SphereCollider (camera.pivot)camera_collider.Radius = 0.45camera_body = New RigidBody (camera.pivot)camera_body.Kinematic = Truecamera_body.Mass = 0' Light setup...light.CastsShadow = Truelight.Range = 1000light.Move (-10, 50, -10)' Point things at ground centre...' camera.WorldPointAt (ground.model.Position)light.PointAt (ground.model)' Create list of PhysBoxes...boxes = New List <PhysBox>' Build wall of PhysBoxes...BuildWall (WALL_WIDTH, WALL_HEIGHT)' Start ground physics...ground.Start ()EndMethod BuildWall (width:Int, height:Int, block_mass:Float = 5.0)Local pb:PhysBox' Creates bunch of PhysBoxes and adds to internal list (boxes)...For Local y:Int = 0 Until heightFor Local x:Int = 0 Until widthLocal color:Color = New Color (Rnd (0.4, 1.0), Rnd (0.4, 1.0), Rnd (0.4, 1.0))' Create new PhysBox...pb = New PhysBox (1, 1, 1, block_mass, New PbrMaterial (color))' Position PhysBox...pb.Move (x - (width * 0.5) + 0.5, y + 1, 0)' Add to list...boxes.Add (pb)' Start its physics...pb.Start () ' False = RigidBody doesn't sleep at restNextNext' Lintel, or "top bit"...pb = New PhysBox (width, 1, 1, width * height * 1.0, New PbrMaterial (Color.Chromium))pb.Move (0, height + 1, 0)boxes.Add (pb)pb.Start ()EndMethod DropBox ()' Drops pink boxes into scene...Local pb:PhysBox = New PhysBox (1, 1, 1, 1, New PbrMaterial (Color.HotPink))pb.Move (0, 30, 0)boxes.Add (pb)pb.Start ()End' Fire bullets!Method ShootBox (force:Float = BULLET_FORCE)' Create bullet -- mass 5.0 -- as child of' camera, to pick up location/rotation...Local pb:PhysBox = New PhysBox (0.75, 0.75, 0.75, 5, New PbrMaterial (Color.Red), camera)' Move forward in local (child) space by 2 units...pb.model.Move (0.0, 0.0, 2.0)' Get rid of parent/child relationship so bullet isn't' attached to camera any more...pb.model.RemoveParent ()' Add to list of PhysBoxes...boxes.Add (pb)' Start physics...pb.Start ()' Apply force (as impulse, ie. instantly)...' Method carefully derived from typing properties and methods until it worked!' World vector multiplied by 1 in all axes other than z, which is multiplied by force...pb.body.ApplyImpulse (pb.model.Basis * New Vec3f (1.0, 1.0, force))EndMethod UpdateBoxes ()For Local pb:PhysBox = Eachin boxesIf pb.model.Y < -20pb.model.Scale = pb.model.Scale * 0.75' Remove when too small...If pb.model.Scale.x < 0.01pb.model.Destroy ()boxes.Remove (pb)EndifEndifNextEndMethod UpdateGame ()' Check box position/remove if too far down...UpdateBoxes ()If Keyboard.KeyHit (Key.Enter)renderer.ResetSeatedPose ()EndifIf Keyboard.KeyHit (Key.Space)ShootBox ()Endif' Drop boxes...If Keyboard.KeyDown (Key.D)DropBox ()Endif' Quit...If Keyboard.KeyHit (Key.Escape)App.Terminate ()Endif' Shadows on/off...If Keyboard.KeyHit (Key.S)light.CastsShadow = Not light.CastsShadowEndif' Rebuild wall...If Keyboard.KeyHit (Key.R)For Local pb:PhysBox = Eachin boxespb.model.Destroy ()boxes.Remove (pb)NextBuildWall (WALL_WIDTH, WALL_HEIGHT)Endif' Speed booster...If Keyboard.KeyDown (Key.LeftShift)camera_speed = CAMERA_SPEED_BOOSTElsecamera_speed = 1.0Endif' Forward...If Keyboard.KeyDown (Key.A)camera.pivot.Move (0.0, 0.0, CAMERA_SPEED_NORMAL * camera_speed)Endif' Back...If Keyboard.KeyDown (Key.Z)camera.pivot.Move (0.0, 0.0, -CAMERA_SPEED_NORMAL * camera_speed)Endif' Rotation...If Keyboard.KeyDown (Key.Left)camera.pivot.Rotate (0.0, 1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Right)camera.pivot.Rotate (0.0, -1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Up)camera.pivot.Rotate (1.0, 0.0, 0.0, True)EndifIf Keyboard.KeyDown (Key.Down)camera.pivot.Rotate (-1.0, 0.0, 0.0, True)EndifEnd' Helper...Method ShadowText:Void (canvas:Canvas, s:String, x:Float, y:Float, warning:Bool = False)canvas.Color = Color.Blackcanvas.DrawText (s, x + 1, y + 1)If warningcanvas.Color = Color.RedElsecanvas.Color = Color.WhiteEndifcanvas.DrawText (s, x, y)EndMethod RenderText (canvas:Canvas)ShadowText (canvas, "FPS: " + App.FPS, 20.0, 20.0)ShadowText (canvas, "A/Z + Cursors to move camera", 20.0, 40.0)ShadowText (canvas, "SHIFT to boost", 20.0, 60.0)ShadowText (canvas, "S to toggle shadows", 20.0, 80.0)ShadowText (canvas, "R to rebuild wall", 20.0, 120.0)ShadowText (canvas, "D to drop more boxes", 20.0, 140.0)ShadowText (canvas, "ENTER to reset position", 20.0, 160.0)ShadowText (canvas, "SPACE to fire", 20.0, 180.0)ShadowText (canvas, "Boxes: " + boxes.Count (), 20.0, 200.0)EndMethod OnRender (canvas:Canvas) OverrideUpdateGame () ' Game-specific updatesRequestRender () ' Ask app window to redrawrenderer.Update () ' Update headset position, etccamera.Update (renderer) ' Update camera from renderer's headset matrixscene.Update () ' Update any physics, etc...scene.Render (canvas) ' Draw VR scene to canvas AND headsetcanvas.DrawRect (0, Height, Width, -Height, renderer.LeftEyeImage)canvas.Scale (Width/App.ActiveWindow.Width, Height/App.ActiveWindow.Height)RenderText (canvas) ' Draw text on desktop window (can't appear in headset at this time)...EndEndFunction Run3D (title:String, width:Int, height:Int, flags:WindowFlags = WindowFlags.Center)New AppInstanceNew Game (title, width, height, flags)App.Run ()EndFunction Main ()Run3D ("3D Scene", 960, 540, WindowFlags.Center) ' 1/4 HD!' Run3D ("3D Scene", 1920, 1080, WindowFlags.Fullscreen)EndFebruary 10, 2018 at 3:57 pm #13604This is an older, hackier demo that loads a 3D model and lets you look around using cursors and A/Z (shift to boost).
For quick results, try downloading the Rio de Janeiro model at Google Poly.
Load it using the file dialog before putting on your headset!
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246[crayon-5cb9a3bd3d953178116123 inline="true" ]' Don't copy the 'crayon' line above if it's there -- forum bug!#Import "<std>"#Import "<mojo>"#Import "<mojo3d>"#Import "<mojo3d-loaders>"#Import "<assimp>"#Import "<mojo3d-vr>"#Import "assets/"Using std..Using mojo..Using mojo3d..' ----------------------------------------' Application name...' ----------------------------------------' Place a supported model anywhere on your PC. Run the program and use the' file dialog (outside of headset!) to select it. Speed/scaling may be' weird, as I don't know what you'll be loading!' Try the .fbx model found at https://poly.google.com/view/2binsxeOBveConst FORMATS_3D:String = "fbx, obj, b3d, gltf, max" ' More available!Global AppName:String = "Viewer 0.0000000000000001... pre-alpha"Function CenterModel:Void (model:Model, scale:Float)' Not bulletproof! 10000 hard-coded, not sure how you get around this...model.Mesh.FitVertices (New Boxf (-10000, 0, -10000, 10000, scale, 10000), True)model.Position = NullEndClass VRScene Extends WindowConst SHIFT_BOOST:Float = 5.0Field renderer:VRRenderer ' VR renderer (duh)Field scene:SceneField cam:ModelField camera:CameraField light:LightField camera_boost:Float = 1.0Field modelpath:StringField model:ModelField scale:Float = 1.0Field copies:Stack <Model>Method New (title:String, width:Int, height:Int, flags:WindowFlags)Super.New (title, width, height, flags)' Create VR renderer and shadow resolution for close-up work,' with more numbers at the lower (closer) end of the range...renderer = New VRRendererscene = Scene.GetCurrent ()scene.CSMSplits = New Float [] (2, 4, 16, 256)scene.ClearColor = New Color (0.1, 0.2, 0.75)scene.AmbientLight = New Color (0.5, 0.5, 0.5)camera = New Camera' Camera settings...camera.Near = 0.1camera.FOV = 90cam = New Modelcamera.Parent = camLoadModel ()light = New Lightlight.CastsShadow = Truelight.Color = New Color (0.95, 0.975, 1.0)light.Range = 1000light.Move (-500, 500, -500)light.PointAt (model)End' This slightly dirty almost-self-contained utility method loads' directly into model:Model field -- ESC from load requester exits app!Method LoadModel:Void ()Local failed:Bool = FalseRepeatIf failed Then Notify ("NOOOOooooo...", "Failed to load " + StripDir (modelpath), True)modelpath = RequestFile ("Select a model, or Cancel/ESC to exit...", FORMATS_3D, False, AssetsDir ())If Not modelpath Then App.Terminate ()ChangeDir (ExtractDir (modelpath))If model Then model.Destroy ()model = Model.Load (modelpath)If Not model Then failed = TrueUntil modelCenterModel (model, 5)scale = 0.25'1.0 ' TEMP HARD-CODED - can't move headset cam!model.Scale = New Vec3f (scale, scale, scale)camera.Position = Nullcamera.Rotation = NullEndMethod UpdateGame:Void ()model.Scale = New Vec3f (scale, scale, scale)EndMethod ProcessInput:Void ()If Keyboard.KeyHit (Key.Space) Then light.CastsShadow = Not light.CastsShadowIf Keyboard.KeyDown (Key.LeftShift)camera_boost = SHIFT_BOOSTElsecamera_boost = 1.0EndifIf Keyboard.KeyHit (Key.Escape)LoadModel ()EndifIf Keyboard.KeyDown (Key.A)cam.Move (0.0, 0.0, 0.1 * camera_boost)EndifIf Keyboard.KeyDown (Key.Z)cam.Move (0.0, 0.0, -0.1 * camera_boost)EndifIf Keyboard.KeyDown (Key.Left)cam.Rotate (0.0, 1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Right)cam.Rotate (0.0, -1.0, 0.0)EndifIf Keyboard.KeyDown (Key.Up)cam.Rotate (1.0, 0.0, 0.0, True)EndifIf Keyboard.KeyDown (Key.Down)cam.Rotate (-1.0, 0.0, 0.0, true)EndifIf Keyboard.KeyDown (Key.Minus) Or Keyboard.KeyDown (Key.KeypadMinus)scale = scale - 0.01EndifIf Keyboard.KeyDown (Key.Equals) Or Keyboard.KeyDown (Key.KeypadPlus)scale = scale + 0.01Endif' NOPE! renderer.HeadMatrix = camera.Matrix ' Set the camera to the user's head position...End' App window drawing (separate to VR headset output)...Method DrawAppWindow (canvas:Canvas, renderer:VRRenderer)' canvas:Canvas comes from OnRender...' renderer:VRRenderer allows access to left/right views from headset...canvas.DrawRect (0, Height, Width, -Height, renderer.LeftEyeImage)canvas.Scale (Width/App.ActiveWindow.Width, Height/App.ActiveWindow.Height)canvas.DrawText ("FPS: " + App.FPS, 0.0, 0.0)canvas.DrawText ("Camera controls: Cursors, plus A/Z (Shift for boost!)", 20.0, 20.0)canvas.DrawText ("ESC to load new model or exit (close dialog)...", 20.0, 40.0)canvas.DrawText ("Model scale (-/+ to change): " + scale, 20.0, 80.0)EndMethod OnRender (canvas:Canvas) OverrideProcessInput ()UpdateGame ()RequestRender ()renderer.Update () ' Update the VR renderer...' Set the camera to the user's head position...camera.SetBasis (renderer.HeadMatrix.m, True)camera.SetPosition (renderer.HeadMatrix.t, True)If renderer.Active Then scene.Update () ' Update the scene if VR is being running...scene.Render (canvas)DrawAppWindow (canvas, renderer) ' Render VR output to non-VR windowEndEnd' All-in-one startup -- width and height relate to non-VR window; rendering is headset-native...Function RunVR (title:String, width:Int, height:Int, flags:WindowFlags = WindowFlags.Center)New AppInstanceNew VRScene (title, width, height, flags)App.Run ()EndFunction Main ()RunVR ("VR Scene", 640, 480, WindowFlags.Center)' RunVR ("VR Scene", 1920, 1080, WindowFlags.Fullscreen)End -
AuthorPosts
You must be logged in to reply to this topic.