309 lines
9.8 KiB
C++
309 lines
9.8 KiB
C++
/*************************************************************************/
|
|
/* 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;
|
|
}
|