/*************************************************************************/ /* File : MyVRManager.h */ /* */ /* Author : Virtools */ /* */ /*************************************************************************/ #include "CKAll.h" #include "VRAll.h" #include "MyVRManager.h" /////////////////////////////////////////////////////////////////////////// MyVRManager::MyVRManager(CKContext *Context, CKBOOL &oError) : VRBaseManager(Context,MyVRManagerGUID,"MyVRManager") { oError = FALSE; // Notes: // + m_VRContext will be in Virtools Dev that do not support the // VRSdk for now. In this case, we don't register our manager. // + Our manager is meaningfull only for the VRPlayer. // + If you intend to compile your dll in the manager directory : // * in the constructor, register your manager only in the CKContext. // * in OnCKInit, register it to the VRContext. if ( !m_VRContext || (m_VRContext->GetExecutionMode()!=VREXECUTION_VRPLAYER) ) { oError = TRUE; return; } // Register for Virtools events m_Context->RegisterNewManager(this); // Register for VR events m_VRContext->RegisterNewManager(this); // Initialization m_WarpFile = ""; m_WarpCamera = NULL; m_WarpMaterial = NULL; } /////////////////////////////////////////////////////////////////////////// MyVRManager::~MyVRManager() { // Nothing to clear } /////////////////////////////////////////////////////////////////////////// CKERROR MyVRManager::OnParse() { CKPathManager* pm = m_Context->GetPathManager(); // Here, we read our tokens. Note that we could also do it when the // first "TestWarping" view is found to avoid reading unneeded tokens. // But as a sample, we do it here. m_TokenOK = TRUE; // Get Warping File. We can use the path manager as all configuration // file search directories have been added to it. m_TokenOK &= (m_VRContext->GetToken("WarpingFile", &m_WarpFile) == VR_OK); pm->ResolveFileName(m_WarpFile, DATA_PATH_IDX); // Get Warping Size. This field are not required, they can use default values m_VRContext->GetToken("WarpingWidth", &m_WarpWidth, 512); m_VRContext->GetToken("WarpingHeight", &m_WarpHeight, 512); // Here, get Additionnal token if needed return VR_OK; } /////////////////////////////////////////////////////////////////////////// CKERROR MyVRManager::OnViewCreate(VRView* iView) { // Get Sub Tokens CKBOOL SubTokenOK = TRUE; /////////////////////////////////////////////////////////////////////// // Activate Warp only when a "Warping" SubToken is specified // Activate mew warp only when warping "Mew" option is set or if ViewMode is ViewWarping XString Warping; if ( m_VRContext->GetSubToken(iView->UserTokens, "Warping", &Warping) != VR_OK ){ m_VRContext->OutputToLog(0, "Warping Warn - Warping will be disabled on view %d.\n", iView->ID); m_VRContext->DeActivateWarp(iView); return VR_OK; } if ( Warping != "SampleWarp" ){ m_VRContext->OutputToLog(0, "Warping Warn - Warping will be disabled on view %d.\n", iView->ID); m_VRContext->DeActivateWarp(iView); return VR_OK; } // General token must be set if ( !m_TokenOK ) { m_VRContext->OutputToLog(0, "Test Warping Err - Tokens 'WarpingFile' must be set for test warping."); m_VRContext->OutputToLog(0, "Test Warping Err - Warping will be disabled on view %d.", iView->ID); m_VRContext->DeActivateWarp(iView); return VR_OK; } /////////////////////////////////////////////////////////////////////// // Get Other Sub Tokens // Get Camera Distance MyWarpData* ViewData = new MyWarpData(); SubTokenOK &= (m_VRContext->GetSubToken(iView->UserTokens, "WarpDistance", &ViewData->Distance, 18.0f)==VR_OK); // We don't force the user to specify this additionnal token, but we could /* if ( !SubTokenOK ) { m_VRContext->OutputToLog(0, "Test Warping Err - View subtokens 'WarpDistance' must be set for test warping."); m_VRContext->OutputToLog(0, "Test Warping Err - Disable mew warping on view %d.", iView->ID); delete (ViewData); return VR_OK; } */ /////////////////////////////////////////////////////////////////////// // Load the warping environment if ( LoadWarpEnvironment() != VR_OK ) { m_VRContext->OutputToLog(0, "Test Warping Err - Could not load the warping environment: %s.", m_WarpFile); delete (ViewData); return VR_OK; } /////////////////////////////////////////////////////////////////////// // Activate Warp WarpInfo WInfo; WInfo.UseWarpTexture = TRUE; WInfo.Width = m_WarpWidth; WInfo.Height = m_WarpHeight; if ( m_VRContext->ActivateWarp(iView, &WInfo) != VR_OK ) { m_VRContext->OutputToLog(0, "Test Warping Err - Could not activate warping."); delete (ViewData); return VR_OK; } /////////////////////////////////////////////////////////////////////// // Memorize distance on the view m_VRContext->SetViewData(iView, (void*) ViewData); return VR_OK; } /////////////////////////////////////////////////////////////////////////// CKERROR MyVRManager::OnViewDelete(VRView* iView) { // We clear the user data we created if ( iView->UserData ) { // Verify we are indeed in SampleWarp configuration XString Warping; if ( m_VRContext->GetSubToken(iView->UserTokens, "Warping", &Warping) != VR_OK ) return VR_OK; if ( Warping != "SampleWarp" ) return VR_OK; // It is our data, delete it. MyWarpData* ViewData = (MyWarpData*) m_VRContext->SetViewData(iView, NULL); delete (ViewData); m_VRContext->DeActivateWarp(iView); } return VR_OK; } /////////////////////////////////////////////////////////////////////////// CKERROR MyVRManager::OnViewWarp(CKRenderContext* rc, VRView* iView) { ////////////////////////////////////////////////////////////////////////// // This commented code shows you how to copy the backbuffer to a texture // when you are not using the warping texture to keep the antialiasing effect. /* if ( !view->WarpTexture ) { VxRect SrcRect, DestRect; SrcRect.left = (float) view->PositionX; SrcRect.top = (float) view->PositionY; SrcRect.right = (float) view->PositionX + view->Width; SrcRect.bottom = (float) view->PositionY + view->Height; DestRect.left = 0; DestRect.top = 0; DestRect.right = (float) view->Width; DestRect.bottom = (float) view->Height; m_MyTexture->CopyContext(rc, &SrcRect, &DestRect); } */ ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // This commented code show you how to erase the background in black whatever // background color is set in Virtools. If you can avoid clearing the background, // it will be faster, but it is sometimes necessery when you require a non black // background material. /* CKMaterial *m = rc->GetBackgroundMaterial(); VxColor bgc = m->GetDiffuse(); CKTexture *bgt = m->GetTexture(); m->SetDiffuse(VxColor(0.0f, 0.0f, 0.0f, 1.0f)); m->SetTexture(NULL); // When using multiple view, you can't clear the entire rendering window, // you have to clear only the viewport. DWORD ro = CK_RENDER_CLEARZ|CK_RENDER_CLEARBACK|CK_RENDER_CLEARSTENCIL; if ( m_VRContext->GetViewCount() > 1 ) ro |= CK_RENDER_CLEARVIEWPORT; rc->Clear((CK_RENDER_FLAGS) ro); */ ////////////////////////////////////////////////////////////////////////// // Save the current transformation matrices. VxMatrix ov = rc->GetViewTransformationMatrix(); VxMatrix op = rc->GetProjectionTransformationMatrix(); // We should set the warping distance here using the view data MyWarpData* ViewData = (MyWarpData*) m_VRContext->GetViewData(iView); // Set Camera Transformation VxMatrix mat; m_WarpCamera->ComputeProjectionMatrix(mat); rc->SetProjectionTransformationMatrix(mat); rc->SetViewTransformationMatrix(m_WarpCamera->GetInverseWorldMatrix()); // Attach the warping texture to the warping object m_WarpMaterial->SetTexture(iView->WarpTexture); // Render the warping screen. m_WarpEntity->Render(rc); // Restore the original tranformation matrices. rc->SetViewTransformationMatrix(ov); rc->SetProjectionTransformationMatrix(op); return VR_OK; } /////////////////////////////////////////////////////////////////////////// CKERROR MyVRManager::LoadWarpEnvironment() { // Environment already loaded if ( m_WarpCamera ) return VR_OK; // Load the file CKObjectArray *array = CreateCKObjectArray(); if ( m_Context->Load(m_WarpFile.Str(), array) != CK_OK ) return VRERR_GENERICERROR; // Mark all the objects as internal and locate the warping objects. CKObject* obj; for(array->Reset() ;!array->EndOfList(); array->Next()) { obj = array->GetData(m_Context); obj->ModifyObjectFlags(CK_OBJECT_NOTTOBEDELETED|CK_OBJECT_PRIVATE, 0); switch ( obj->GetClassID() ) { case CKCID_CAMERA: case CKCID_TARGETCAMERA: m_WarpCamera = (CKCamera*) obj; break; case CKCID_3DOBJECT: m_WarpEntity = (CK3dEntity*) obj; break; case CKCID_MESH: m_WarpMesh = (CKMesh*) obj; break; case CKCID_MATERIAL: m_WarpMaterial = (CKMaterial*) obj; break; } } // Verify that the object were succesfully loaded if ( !m_WarpEntity || !m_WarpMesh || !m_WarpMaterial || !m_WarpCamera ) { for(array->Reset() ;!array->EndOfList(); array->Next()) CKDestroyObject( array->GetData(m_Context) ); DeleteCKObjectArray(array); return VRERR_GENERICERROR; } // We must remove the camera aspect ratio for VRPlayer multiple views m_WarpCamera->SetFlags(m_WarpCamera->GetFlags()|CK_3DENTITY_CAMERAIGNOREASPECT); // Force some mesh options : object must be prelited, not light computation is done. m_WarpMesh->SetLitMode(VX_PRELITMESH); // Set material texture option m_WarpMaterial->SetTextureAddressMode(VXTEXTURE_ADDRESSWRAP); m_WarpMaterial->SetTextureMagMode(VXTEXTUREFILTER_LINEAR); m_WarpMaterial->SetTextureMinMode(VXTEXTUREFILTER_LINEAR); m_WarpMaterial->SetTextureBlendMode(VXTEXTUREBLEND_MODULATE); // Delete Array DeleteCKObjectArray(array); return VR_OK; }