aboutsummaryrefslogtreecommitdiffstats
path: root/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp
diff options
context:
space:
mode:
authorBrad Davis <[email protected]>2014-04-14 21:25:09 -0700
committerBrad Davis <[email protected]>2014-04-14 21:25:09 -0700
commit07d0f4d0bbf3477ac6a9584f726e8ec6ab285707 (patch)
tree1854d0c690eff32e77b137567c88a52d56d8b660 /Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp
parentf28388ff2af14b56ef2d973b2f4f9da021716d4c (diff)
Adding windows 0.3.1 SDK
Diffstat (limited to 'Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp')
-rw-r--r--Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp399
1 files changed, 399 insertions, 0 deletions
diff --git a/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp b/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp
new file mode 100644
index 0000000..5dfe2d2
--- /dev/null
+++ b/Samples/OculusWorldDemo/OculusWorldDemo_Scene.cpp
@@ -0,0 +1,399 @@
+/************************************************************************************
+
+Filename : OculusWorldDemo_Scene.cpp
+Content : Logic for loading, and creating rendered scene components,
+ cube and grid overlays, etc.
+Created : October 4, 2012
+Authors : Michael Antonov, Andrew Reisse, Steve LaValle, Dov Katz
+ Peter Hoff, Dan Goodman, Bryan Croteau
+
+Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+*************************************************************************************/
+
+#include "OculusWorldDemo.h"
+
+
+//-------------------------------------------------------------------------------------
+// ***** Scene Creation / Loading
+
+void OculusWorldDemoApp::InitMainFilePath()
+{
+
+ MainFilePath = WORLDDEMO_ASSET_FILE;
+
+ // Try to modify path for correctness in case specified file is not found.
+ if (!SysFile(MainFilePath).IsValid())
+ {
+ String prefixPath1(pPlatform->GetContentDirectory() + "/" + WORLDDEMO_ASSET_PATH1),
+ prefixPath2(WORLDDEMO_ASSET_PATH2),
+ prefixPath3(WORLDDEMO_ASSET_PATH3);
+ if (SysFile(prefixPath1 + MainFilePath).IsValid())
+ MainFilePath = prefixPath1 + MainFilePath;
+ else if (SysFile(prefixPath2 + MainFilePath).IsValid())
+ MainFilePath = prefixPath2 + MainFilePath;
+ else if (SysFile(prefixPath3 + MainFilePath).IsValid())
+ MainFilePath = prefixPath3 + MainFilePath;
+ }
+}
+
+// Creates a grid of cubes.
+void PopulateCubeFieldScene(Scene* scene, Fill* fill,
+ int cubeCountX, int cubeCountY, int cubeCountZ, Vector3f offset,
+ float cubeSpacing = 0.5f, float cubeSize = 0.1f)
+{
+
+ Vector3f corner(-(((cubeCountX-1) * cubeSpacing) + cubeSize) * 0.5f,
+ -(((cubeCountY-1) * cubeSpacing) + cubeSize) * 0.5f,
+ -(((cubeCountZ-1) * cubeSpacing) + cubeSize) * 0.5f);
+ corner += offset;
+
+ Vector3f pos = corner;
+
+ for (int i = 0; i < cubeCountX; i++)
+ {
+ // Create a new model for each 'plane' of cubes so we don't exceed
+ // the vert size limit.
+ Ptr<Model> model = *new Model();
+ scene->World.Add(model);
+
+ if (fill)
+ model->Fill = fill;
+
+ for (int j = 0; j < cubeCountY; j++)
+ {
+ for (int k = 0; k < cubeCountZ; k++)
+ {
+ model->AddBox(0xFFFFFFFF, pos, Vector3f(cubeSize, cubeSize, cubeSize));
+ pos.z += cubeSpacing;
+ }
+
+ pos.z = corner.z;
+ pos.y += cubeSpacing;
+ }
+
+ pos.y = corner.y;
+ pos.x += cubeSpacing;
+ }
+}
+
+Fill* CreateTexureFill(RenderDevice* prender, const String& filename)
+{
+ Ptr<File> imageFile = *new SysFile(filename);
+ Ptr<Texture> imageTex;
+ if (imageFile->IsValid())
+ imageTex = *LoadTextureTga(prender, imageFile);
+
+ // Image is rendered as a single quad.
+ ShaderFill* fill = 0;
+ if (imageTex)
+ {
+ imageTex->SetSampleMode(Sample_Anisotropic|Sample_Repeat);
+ fill = new ShaderFill(*prender->CreateShaderSet());
+ fill->GetShaders()->SetShader(prender->LoadBuiltinShader(Shader_Vertex, VShader_MVP));
+ fill->GetShaders()->SetShader(prender->LoadBuiltinShader(Shader_Fragment, FShader_Texture));
+ fill->SetTexture(0, imageTex);
+ }
+
+ return fill;
+}
+
+
+// Loads the scene data
+void OculusWorldDemoApp::PopulateScene(const char *fileName)
+{
+ XmlHandler xmlHandler;
+ if(!xmlHandler.ReadFile(fileName, pRender, &MainScene, &CollisionModels, &GroundCollisionModels))
+ {
+ Menu.SetPopupMessage("FILE LOAD FAILED");
+ Menu.SetPopupTimeout(10.0f, true);
+ }
+
+ MainScene.SetAmbient(Color4f(1.0f, 1.0f, 1.0f, 1.0f));
+
+ // Handy cube.
+ Ptr<Model> smallGreenCubeModel = *Model::CreateBox(Color(0, 255, 0, 255), Vector3f(0.0f, 0.0f, 0.0f), Vector3f(0.004f, 0.004f, 0.004f));
+ SmallGreenCube.World.Add(smallGreenCubeModel);
+
+ String mainFilePathNoExtension = MainFilePath;
+ mainFilePathNoExtension.StripExtension();
+
+
+ // 10x10x10 cubes.
+ Ptr<Fill> fillR = *CreateTexureFill(pRender, mainFilePathNoExtension + "_redCube.tga");
+ PopulateCubeFieldScene(&RedCubesScene, fillR.GetPtr(), 10, 10, 10, Vector3f(0.0f, 0.0f, 0.0f), 0.4f);
+
+ // 10x10x10 cubes.
+ Ptr<Fill> fillB = *CreateTexureFill(pRender, mainFilePathNoExtension + "_blueCube.tga");
+ PopulateCubeFieldScene(&BlueCubesScene, fillB.GetPtr(), 10, 10, 10, Vector3f(0.0f, 0.0f, 0.0f), 0.4f);
+
+ // Anna: OculusWorldDemo/Assets/Tuscany/Tuscany_OculusCube.tga file needs to be added
+ Ptr<Fill> imageFill = *CreateTexureFill(pRender, mainFilePathNoExtension + "_OculusCube.tga");
+ PopulateCubeFieldScene(&OculusCubesScene, imageFill.GetPtr(), 11, 4, 35, Vector3f(0.0f, 0.0f, -6.0f), 0.5f);
+
+
+ float r = 0.01f;
+ Ptr<Model> purpleCubesModel = *new Model(Prim_Triangles);
+ for (int i = 0; i < 10; i++)
+ for (int j = 0; j < 10; j++)
+ for (int k = 0; k < 10; k++)
+ purpleCubesModel->AddSolidColorBox(i*0.25f-1.25f-r,j*0.25f-1.25f-r,k*0.25f-1.25f-r,
+ i*0.25f-1.25f+r,j*0.25f-1.25f+r,k*0.25f-1.25f+r,0xFF9F009F);
+}
+
+
+void OculusWorldDemoApp::PopulatePreloadScene()
+{
+ // Load-screen screen shot image
+ String fileName = MainFilePath;
+ fileName.StripExtension();
+
+ Ptr<File> imageFile = *new SysFile(fileName + "_LoadScreen.tga");
+ Ptr<Texture> imageTex;
+ if (imageFile->IsValid())
+ imageTex = *LoadTextureTga(pRender, imageFile);
+
+ // Image is rendered as a single quad.
+ if (imageTex)
+ {
+ imageTex->SetSampleMode(Sample_Anisotropic|Sample_Repeat);
+ Ptr<Model> m = *new Model(Prim_Triangles);
+ m->AddVertex(-0.5f, 0.5f, 0.0f, Color(255,255,255,255), 0.0f, 0.0f);
+ m->AddVertex( 0.5f, 0.5f, 0.0f, Color(255,255,255,255), 1.0f, 0.0f);
+ m->AddVertex( 0.5f, -0.5f, 0.0f, Color(255,255,255,255), 1.0f, 1.0f);
+ m->AddVertex(-0.5f, -0.5f, 0.0f, Color(255,255,255,255), 0.0f, 1.0f);
+ m->AddTriangle(2,1,0);
+ m->AddTriangle(0,3,2);
+
+ Ptr<ShaderFill> fill = *new ShaderFill(*pRender->CreateShaderSet());
+ fill->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Vertex, VShader_MVP));
+ fill->GetShaders()->SetShader(pRender->LoadBuiltinShader(Shader_Fragment, FShader_Texture));
+ fill->SetTexture(0, imageTex);
+ m->Fill = fill;
+
+ LoadingScene.World.Add(m);
+ }
+}
+
+void OculusWorldDemoApp::ClearScene()
+{
+ MainScene.Clear();
+ SmallGreenCube.Clear();
+}
+
+
+//-------------------------------------------------------------------------------------
+// ***** Rendering Content
+
+
+void OculusWorldDemoApp::RenderAnimatedBlocks(ovrEyeType eye, double appTime)
+{
+ Matrix4f viewAdjust = Matrix4f::Translation(Vector3f(EyeRenderDesc[eye].ViewAdjust));
+
+ switch ( BlocksShowType )
+ {
+ case 0:
+ // No blocks;
+ break;
+ case 1: {
+ // Horizontal circle around your head.
+ int const numBlocks = 10;
+ float const radius = 1.0f;
+ Matrix4f scaleUp = Matrix4f::Scaling ( 20.0f );
+ double scaledTime = appTime * 0.1;
+ float fracTime = (float)( scaledTime - floor ( scaledTime ) );
+
+ for ( int j = 0; j < 2; j++ )
+ {
+ for ( int i = 0; i < numBlocks; i++ )
+ {
+ float angle = ( ( (float)i / numBlocks ) + fracTime ) * ( Math<float>::Pi * 2.0f );
+ Vector3f pos;
+ pos.x = BlocksCenter.x + radius * cosf ( angle );
+ pos.y = BlocksCenter.y;
+ pos.z = BlocksCenter.z + radius * sinf ( angle );
+ if ( j == 0 )
+ {
+ pos.x = BlocksCenter.x - radius * cosf ( angle );
+ pos.y = BlocksCenter.y - 0.5f;
+ }
+ Matrix4f mat = Matrix4f::Translation ( pos );
+ SmallGreenCube.Render(pRender, viewAdjust * View * mat * scaleUp);
+ }
+ }
+ }break;
+
+ case 2: {
+ // Vertical circle around your head.
+ int const numBlocks = 10;
+ float const radius = 1.0f;
+ Matrix4f scaleUp = Matrix4f::Scaling ( 20.0f );
+ double scaledTime = appTime * 0.1;
+ float fracTime = (float)( scaledTime - floor ( scaledTime ) );
+
+ for ( int j = 0; j < 2; j++ )
+ {
+ for ( int i = 0; i < numBlocks; i++ )
+ {
+ float angle = ( ( (float)i / numBlocks ) + fracTime ) * ( Math<float>::Pi * 2.0f );
+ Vector3f pos;
+ pos.x = BlocksCenter.x;
+ pos.y = BlocksCenter.y + radius * cosf ( angle );
+ pos.z = BlocksCenter.z + radius * sinf ( angle );
+ if ( j == 0 )
+ {
+ pos.x = BlocksCenter.x - 0.5f;
+ pos.y = BlocksCenter.y - radius * cosf ( angle );
+ }
+ Matrix4f mat = Matrix4f::Translation ( pos );
+ SmallGreenCube.Render(pRender, viewAdjust * View * mat * scaleUp);
+ }
+ }
+ }break;
+
+ case 3:{
+ // Bouncing.
+ int const numBlocks = 10;
+ Matrix4f scaleUp = Matrix4f::Scaling ( 20.0f );
+
+ for ( int i = 0; i < numBlocks; i++ )
+ {
+ double scaledTime = 4.0f * appTime / (double)i;
+ float fracTime = (float)( scaledTime - floor ( scaledTime ) );
+
+ Vector3f pos = BlocksCenter;
+ pos.z += (float)i;
+ pos.y += -1.5f + 4.0f * ( 2.0f * fracTime * ( 1.0f - fracTime ) );
+ Matrix4f mat = Matrix4f::Translation ( pos );
+ SmallGreenCube.Render(pRender, viewAdjust * View * mat * scaleUp);
+ }
+ }break;
+
+ default:
+ BlocksShowType = 0;
+ break;
+ }
+}
+
+void OculusWorldDemoApp::RenderGrid(ovrEyeType eye)
+{
+ Recti renderViewport = EyeTexture[eye].Header.RenderViewport;
+
+ // Draw actual pixel grid on the RT.
+ // 1:1 mapping to screen pixels, origin in top-left.
+ Matrix4f ortho;
+ ortho.SetIdentity();
+ ortho.M[0][0] = 2.0f / (renderViewport.w); // X scale
+ ortho.M[0][3] = -1.0f; // X offset
+ ortho.M[1][1] = -2.0f / (renderViewport.h); // Y scale (for Y=down)
+ ortho.M[1][3] = 1.0f; // Y offset (Y=down)
+ ortho.M[2][2] = 0;
+ pRender->SetProjection(ortho);
+
+ pRender->SetDepthMode(false, false);
+ Color cNormal ( 255, 0, 0 );
+ Color cSpacer ( 255, 255, 0 );
+ Color cMid ( 0, 128, 255 );
+
+ int lineStep = 1;
+ int midX = 0;
+ int midY = 0;
+ int limitX = 0;
+ int limitY = 0;
+
+ switch ( GridMode )
+ {
+ case Grid_Rendertarget4:
+ lineStep = 4;
+ midX = renderViewport.w / 2;
+ midY = renderViewport.h / 2;
+ limitX = renderViewport.w / 2;
+ limitY = renderViewport.h / 2;
+ break;
+ case Grid_Rendertarget16:
+ lineStep = 16;
+ midX = renderViewport.w / 2;
+ midY = renderViewport.h / 2;
+ limitX = renderViewport.w / 2;
+ limitY = renderViewport.h / 2;
+ break;
+ case Grid_Lens:
+ {
+ lineStep = 48;
+ Vector2f rendertargetNDC = FovPort(EyeRenderDesc[eye].Desc.Fov).TanAngleToRendertargetNDC(Vector2f(0.0f));
+ midX = (int)( ( rendertargetNDC.x * 0.5f + 0.5f ) * (float)renderViewport.w + 0.5f );
+ midY = (int)( ( rendertargetNDC.y * 0.5f + 0.5f ) * (float)renderViewport.h + 0.5f );
+ limitX = Alg::Max ( renderViewport.w - midX, midX );
+ limitY = Alg::Max ( renderViewport.h - midY, midY );
+ }
+ break;
+ default: OVR_ASSERT ( false ); break;
+ }
+
+ int spacerMask = (lineStep<<2)-1;
+
+
+ for ( int xp = 0; xp < limitX; xp += lineStep )
+ {
+ float x[4];
+ float y[4];
+ x[0] = (float)( midX + xp );
+ y[0] = (float)0;
+ x[1] = (float)( midX + xp );
+ y[1] = (float)renderViewport.h;
+ x[2] = (float)( midX - xp );
+ y[2] = (float)0;
+ x[3] = (float)( midX - xp );
+ y[3] = (float)renderViewport.h;
+ if ( xp == 0 )
+ {
+ pRender->RenderLines ( 1, cMid, x, y );
+ }
+ else if ( ( xp & spacerMask ) == 0 )
+ {
+ pRender->RenderLines ( 2, cSpacer, x, y );
+ }
+ else
+ {
+ pRender->RenderLines ( 2, cNormal, x, y );
+ }
+ }
+ for ( int yp = 0; yp < limitY; yp += lineStep )
+ {
+ float x[4];
+ float y[4];
+ x[0] = (float)0;
+ y[0] = (float)( midY + yp );
+ x[1] = (float)renderViewport.w;
+ y[1] = (float)( midY + yp );
+ x[2] = (float)0;
+ y[2] = (float)( midY - yp );
+ x[3] = (float)renderViewport.w;
+ y[3] = (float)( midY - yp );
+ if ( yp == 0 )
+ {
+ pRender->RenderLines ( 1, cMid, x, y );
+ }
+ else if ( ( yp & spacerMask ) == 0 )
+ {
+ pRender->RenderLines ( 2, cSpacer, x, y );
+ }
+ else
+ {
+ pRender->RenderLines ( 2, cNormal, x, y );
+ }
+ }
+}
+