2016-06-14 23:12:27 +00:00
# include "platform/platform.h"
# include "platform/input/openVR/openVRTrackedObject.h"
# include "platform/input/openVR/openVRProvider.h"
# include "math/mathIO.h"
# include "scene/sceneRenderState.h"
# include "console/consoleTypes.h"
# include "core/stream/bitStream.h"
# include "core/resourceManager.h"
# include "materials/materialManager.h"
# include "materials/baseMatInstance.h"
# include "renderInstance/renderPassManager.h"
# include "lighting/lightQuery.h"
# include "console/engineAPI.h"
# include "gfx/gfxTextureManager.h"
# include "gfx/sim/debugDraw.h"
# include "gfx/gfxTransformSaver.h"
# include "environment/skyBox.h"
# include "collision/boxConvex.h"
# include "collision/concretePolyList.h"
# include "T3D/physics/physicsPlugin.h"
# include "T3D/physics/physicsCollision.h"
# include "T3D/physics/physicsBody.h"
# ifdef TORQUE_EXTENDED_MOVE
# include "T3D/gameBase/extended/extendedMove.h"
# endif
bool OpenVRTrackedObject : : smDebugControllerMovePosition = true ;
bool OpenVRTrackedObject : : smDebugControllerPosition = false ;
static const U32 sCollisionMoveMask = ( PlayerObjectType |
2016-07-12 22:30:11 +00:00
StaticShapeObjectType | VehicleObjectType ) ;
2016-06-14 23:12:27 +00:00
U32 OpenVRTrackedObject : : sServerCollisionMask = sCollisionMoveMask ; // ItemObjectType
U32 OpenVRTrackedObject : : sClientCollisionMask = sCollisionMoveMask ;
//-----------------------------------------------------------------------------
IMPLEMENT_CO_DATABLOCK_V1 ( OpenVRTrackedObjectData ) ;
OpenVRTrackedObjectData : : OpenVRTrackedObjectData ( ) :
mShapeFile ( NULL )
{
2016-07-12 22:30:11 +00:00
mCollisionBoxMin = Point3F ( - 0.02 , - 0.20 , - 0.02 ) ;
mCollisionBoxMax = Point3F ( 0.02 , 0.05 , 0.02 ) ;
2016-06-14 23:12:27 +00:00
}
OpenVRTrackedObjectData : : ~ OpenVRTrackedObjectData ( )
{
}
bool OpenVRTrackedObjectData : : onAdd ( )
{
2016-07-12 22:30:11 +00:00
if ( Parent : : onAdd ( ) )
{
return true ;
}
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
return false ;
2016-06-14 23:12:27 +00:00
}
bool OpenVRTrackedObjectData : : preload ( bool server , String & errorStr )
{
2016-07-12 22:30:11 +00:00
if ( ! Parent : : preload ( server , errorStr ) )
return false ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
bool error = false ;
if ( ! server )
{
mShape = mShapeFile ? ResourceManager : : get ( ) . load ( mShapeFile ) : NULL ;
}
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObjectData : : initPersistFields ( )
{
2016-07-12 22:30:11 +00:00
addGroup ( " Render Components " ) ;
addField ( " shape " , TypeShapeFilename , Offset ( mShapeFile , OpenVRTrackedObjectData ) , " Shape file to use for controller model. " ) ;
addField ( " collisionMin " , TypePoint3F , Offset ( mCollisionBoxMin , OpenVRTrackedObjectData ) , " Box min " ) ;
addField ( " collisionMax " , TypePoint3F , Offset ( mCollisionBoxMax , OpenVRTrackedObjectData ) , " Box min " ) ;
endGroup ( " Render Components " ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
Parent : : initPersistFields ( ) ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObjectData : : packData ( BitStream * stream )
{
2016-07-12 22:30:11 +00:00
Parent : : packData ( stream ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
stream - > writeString ( mShapeFile ) ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObjectData : : unpackData ( BitStream * stream )
{
2016-07-12 22:30:11 +00:00
Parent : : unpackData ( stream ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
mShapeFile = stream - > readSTString ( ) ;
2016-06-14 23:12:27 +00:00
}
//-----------------------------------------------------------------------------
IMPLEMENT_CO_NETOBJECT_V1 ( OpenVRTrackedObject ) ;
ConsoleDocClass ( OpenVRTrackedObject ,
2016-07-12 22:30:11 +00:00
" @brief Renders and handles interactions OpenVR controllers and tracked objects. \n \n "
" This class implements basic rendering and interactions with OpenVR controllers. \n \n "
" The object should be controlled by a player object. Controllers will be rendered at \n "
" the correct position regardless of the current transform of the object. \n "
" @ingroup OpenVR \n " ) ;
2016-06-14 23:12:27 +00:00
//-----------------------------------------------------------------------------
// Object setup and teardown
//-----------------------------------------------------------------------------
OpenVRTrackedObject : : OpenVRTrackedObject ( ) :
mDataBlock ( NULL ) ,
mShapeInstance ( NULL ) ,
mBasicModel ( NULL ) ,
mDeviceIndex ( - 1 ) ,
mMappedMoveIndex ( - 1 ) ,
mIgnoreParentRotation ( true ) ,
mConvexList ( new Convex ( ) ) ,
mPhysicsRep ( NULL )
{
2016-07-12 22:30:11 +00:00
// Flag this object so that it will always
// be sent across the network to clients
mNetFlags . set ( Ghostable | ScopeAlways ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
// Set it as a "static" object that casts shadows
mTypeMask | = StaticObjectType | StaticShapeObjectType ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
mPose . connected = false ;
2016-06-14 23:12:27 +00:00
}
OpenVRTrackedObject : : ~ OpenVRTrackedObject ( )
{
2016-07-12 22:30:11 +00:00
clearRenderData ( ) ;
delete mConvexList ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : updateRenderData ( )
{
2016-07-12 22:30:11 +00:00
clearRenderData ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
if ( ! mDataBlock )
return ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
// Are we using a model?
if ( mDataBlock - > mShape )
{
if ( mShapeInstance & & mShapeInstance - > getShape ( ) ! = mDataBlock - > mShape )
{
delete mShapeInstance ;
mShapeInstance = NULL ;
}
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
if ( ! mShapeInstance )
{
mShapeInstance = new TSShapeInstance ( mDataBlock - > mShape , isClientObject ( ) ) ;
}
}
else
{
setupRenderDataFromModel ( isClientObject ( ) ) ;
}
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : setupRenderDataFromModel ( bool loadComponentModels )
{
2016-07-12 22:30:11 +00:00
clearRenderData ( ) ;
if ( ! OPENVR | | ! OPENVR - > isEnabled ( ) )
return ;
vr : : IVRRenderModels * models = OPENVR - > getRenderModels ( ) ;
if ( ! models )
return ;
if ( ! mShapeInstance & & mModelName & & mModelName [ 0 ] ! = ' \0 ' )
{
bool failed = false ;
S32 idx = OPENVR - > preloadRenderModel ( mModelName ) ;
while ( ! OPENVR - > getRenderModel ( idx , & mBasicModel , failed ) )
{
if ( failed )
break ;
}
}
if ( loadComponentModels )
{
mRenderComponents . setSize ( models - > GetComponentCount ( mModelName ) ) ;
for ( U32 i = 0 , sz = mRenderComponents . size ( ) ; i < sz ; i + + )
{
RenderModelSlot & slot = mRenderComponents [ i ] ;
char buffer [ 1024 ] ;
slot . mappedNodeIdx = - 1 ;
slot . componentName = NULL ;
slot . nativeModel = NULL ;
U32 result = models - > GetComponentName ( mModelName , i , buffer , sizeof ( buffer ) ) ;
if ( result = = 0 )
continue ;
2016-06-14 23:12:27 +00:00
# ifdef DEBUG_CONTROLLER_MODELS
2016-07-12 22:30:11 +00:00
Con : : printf ( " Controller[%s] component %i NAME == %s " , mModelName , i , buffer ) ;
2016-06-14 23:12:27 +00:00
# endif
2016-07-12 22:30:11 +00:00
slot . componentName = StringTable - > insert ( buffer , true ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
result = models - > GetComponentRenderModelName ( mModelName , slot . componentName , buffer , sizeof ( buffer ) ) ;
if ( result = = 0 )
{
2016-06-14 23:12:27 +00:00
# ifdef DEBUG_CONTROLLER_MODELS
2016-07-12 22:30:11 +00:00
Con : : printf ( " Controller[%s] component %i NO MODEL " , mModelName , i ) ;
2016-06-14 23:12:27 +00:00
# endif
2016-07-12 22:30:11 +00:00
continue ;
}
2016-06-14 23:12:27 +00:00
# ifdef DEBUG_CONTROLLER_MODELS
2016-07-12 22:30:11 +00:00
Con : : printf ( " Controller[%s] component %i == %s " , mModelName , i , slot . componentName ) ;
2016-06-14 23:12:27 +00:00
# endif
2016-07-12 22:30:11 +00:00
bool failed = false ;
S32 idx = OPENVR - > preloadRenderModel ( StringTable - > insert ( buffer , true ) ) ;
while ( ! OPENVR - > getRenderModel ( idx , & slot . nativeModel , failed ) )
{
if ( failed )
break ;
}
}
}
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : clearRenderData ( )
{
2016-07-12 22:30:11 +00:00
mBasicModel = NULL ;
mRenderComponents . clear ( ) ;
2016-06-14 23:12:27 +00:00
}
//-----------------------------------------------------------------------------
// Object Editing
//-----------------------------------------------------------------------------
void OpenVRTrackedObject : : initPersistFields ( )
{
2016-07-12 22:30:11 +00:00
// SceneObject already handles exposing the transform
Parent : : initPersistFields ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
addField ( " deviceIndex " , TypeS32 , Offset ( mDeviceIndex , OpenVRTrackedObject ) , " Index of device to track " ) ;
addField ( " mappedMoveIndex " , TypeS32 , Offset ( mMappedMoveIndex , OpenVRTrackedObject ) , " Index of movemanager state to track " ) ; addField ( " deviceIndex " , TypeS32 , Offset ( mDeviceIndex , OpenVRTrackedObject ) , " Index of device to track " ) ;
addField ( " ignoreParentRotation " , TypeBool , Offset ( mIgnoreParentRotation , OpenVRTrackedObject ) , " Index of movemanager state to track " ) ; addField ( " deviceIndex " , TypeS32 , Offset ( mDeviceIndex , OpenVRTrackedObject ) , " Index of device to track " ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
static bool conInit = false ;
if ( ! conInit )
{
Con : : addVariable ( " $OpenVRTrackedObject::debugControllerPosition " , TypeBool , & smDebugControllerPosition ) ;
Con : : addVariable ( " $OpenVRTrackedObject::debugControllerMovePosition " , TypeBool , & smDebugControllerMovePosition ) ;
conInit = true ;
}
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : inspectPostApply ( )
{
2016-07-12 22:30:11 +00:00
Parent : : inspectPostApply ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
// Flag the network mask to send the updates
// to the client object
setMaskBits ( UpdateMask ) ;
2016-06-14 23:12:27 +00:00
}
bool OpenVRTrackedObject : : onAdd ( )
{
2016-07-12 22:30:11 +00:00
if ( ! Parent : : onAdd ( ) )
return false ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
// Set up a 1x1x1 bounding box
mObjBox . set ( Point3F ( - 0.5f , - 0.5f , - 0.5f ) ,
Point3F ( 0.5f , 0.5f , 0.5f ) ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
resetWorldBox ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
// Add this object to the scene
addToScene ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
if ( mDataBlock )
{
mObjBox . minExtents = mDataBlock - > mCollisionBoxMin ;
mObjBox . maxExtents = mDataBlock - > mCollisionBoxMax ;
resetWorldBox ( ) ;
}
else
{
setGlobalBounds ( ) ;
}
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
return true ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : onRemove ( )
{
2016-07-12 22:30:11 +00:00
// Remove this object from the scene
removeFromScene ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
clearRenderData ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
SAFE_DELETE ( mPhysicsRep ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
Parent : : onRemove ( ) ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : _updatePhysics ( )
{
2016-07-12 22:30:11 +00:00
SAFE_DELETE ( mPhysicsRep ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
if ( ! PHYSICSMGR )
return ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
PhysicsCollision * colShape = NULL ;
MatrixF offset ( true ) ;
colShape = PHYSICSMGR - > createCollision ( ) ;
colShape - > addBox ( getObjBox ( ) . getExtents ( ) * 0.5f * mObjScale , offset ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
if ( colShape )
{
PhysicsWorld * world = PHYSICSMGR - > getWorld ( isServerObject ( ) ? " server " : " client " ) ;
mPhysicsRep = PHYSICSMGR - > createBody ( ) ;
mPhysicsRep - > init ( colShape , 0 , PhysicsBody : : BF_TRIGGER | PhysicsBody : : BF_KINEMATIC , this , world ) ;
mPhysicsRep - > setTransform ( getTransform ( ) ) ;
}
2016-06-14 23:12:27 +00:00
}
bool OpenVRTrackedObject : : onNewDataBlock ( GameBaseData * dptr , bool reload )
{
2016-07-12 22:30:11 +00:00
mDataBlock = dynamic_cast < OpenVRTrackedObjectData * > ( dptr ) ;
if ( ! mDataBlock | | ! Parent : : onNewDataBlock ( dptr , reload ) )
return false ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
// Setup the models
clearRenderData ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
mObjBox . minExtents = mDataBlock - > mCollisionBoxMin ;
mObjBox . maxExtents = mDataBlock - > mCollisionBoxMax ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
mGlobalBounds = false ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
resetWorldBox ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
_updatePhysics ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
scriptOnNewDataBlock ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
return true ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : setInteractObject ( SceneObject * object , bool holding )
{
2016-07-12 22:30:11 +00:00
mInteractObject = object ;
mHoldInteractedObject = holding ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : setTransform ( const MatrixF & mat )
{
2016-07-12 22:30:11 +00:00
// Let SceneObject handle all of the matrix manipulation
Parent : : setTransform ( mat ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
// Dirty our network mask so that the new transform gets
// transmitted to the client object
setMaskBits ( UpdateMask ) ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : setModelName ( String & modelName )
{
2016-07-12 22:30:11 +00:00
if ( ! isServerObject ( ) )
return ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
mModelName = StringTable - > insert ( modelName . c_str ( ) , true ) ;
setMaskBits ( UpdateMask ) ;
2016-06-14 23:12:27 +00:00
}
U32 OpenVRTrackedObject : : packUpdate ( NetConnection * conn , U32 mask , BitStream * stream )
{
2016-07-12 22:30:11 +00:00
// Allow the Parent to get a crack at writing its info
U32 retMask = Parent : : packUpdate ( conn , mask , stream ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
// Write our transform information
if ( stream - > writeFlag ( mask & UpdateMask ) )
{
mathWrite ( * stream , getTransform ( ) ) ;
mathWrite ( * stream , getScale ( ) ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
stream - > write ( ( S16 ) mDeviceIndex ) ;
stream - > write ( ( S16 ) mMappedMoveIndex ) ;
stream - > writeString ( mModelName ) ;
}
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
return retMask ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : unpackUpdate ( NetConnection * conn , BitStream * stream )
{
2016-07-12 22:30:11 +00:00
// Let the Parent read any info it sent
Parent : : unpackUpdate ( conn , stream ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
if ( stream - > readFlag ( ) ) // UpdateMask
{
mathRead ( * stream , & mObjToWorld ) ;
mathRead ( * stream , & mObjScale ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
setTransform ( mObjToWorld ) ;
S16 readDeviceIndex ;
S16 readMoveIndex ;
stream - > read ( & readDeviceIndex ) ;
stream - > read ( & readMoveIndex ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
mDeviceIndex = readDeviceIndex ;
mMappedMoveIndex = readMoveIndex ;
mModelName = stream - > readSTString ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
updateRenderData ( ) ;
}
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : writePacketData ( GameConnection * conn , BitStream * stream )
{
2016-07-12 22:30:11 +00:00
Parent : : writePacketData ( conn , stream ) ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : readPacketData ( GameConnection * conn , BitStream * stream )
{
2016-07-12 22:30:11 +00:00
Parent : : readPacketData ( conn , stream ) ;
2016-06-14 23:12:27 +00:00
}
MatrixF OpenVRTrackedObject : : getTrackedTransform ( )
{
2016-07-12 22:30:11 +00:00
IDevicePose pose = OPENVR - > getTrackedDevicePose ( mDeviceIndex ) ;
MatrixF trackedMat ( 1 ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
pose . orientation . setMatrix ( & trackedMat ) ;
trackedMat . setPosition ( pose . position ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
return trackedMat ;
2016-06-14 23:12:27 +00:00
}
MatrixF OpenVRTrackedObject : : getLastTrackedTransform ( )
{
2016-07-12 22:30:11 +00:00
MatrixF trackedMat ( 1 ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
mPose . orientation . setMatrix ( & trackedMat ) ;
trackedMat . setPosition ( mPose . position ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
return trackedMat ;
2016-06-14 23:12:27 +00:00
}
MatrixF OpenVRTrackedObject : : getBaseTrackingTransform ( )
{
2016-07-12 22:30:11 +00:00
if ( isMounted ( ) )
{
MatrixF mat ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
mMount . object - > getMountTransform ( mMount . node , mMount . xfm , & mat ) ;
if ( mIgnoreParentRotation )
{
Point3F pos = mat . getPosition ( ) ;
mat = MatrixF ( 1 ) ;
mat . setPosition ( pos ) ;
}
//mat.inverse();
return mat ;
}
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
return MatrixF ( 1 ) ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : prepRenderImage ( SceneRenderState * state )
{
2016-07-12 22:30:11 +00:00
RenderPassManager * renderPass = state - > getRenderPass ( ) ;
// debug rendering for now
if ( mDeviceIndex < 0 )
return ;
// Current pose
IDevicePose pose = OPENVR - > getTrackedDevicePose ( mDeviceIndex ) ;
IDevicePose hmdPose = OPENVR - > getTrackedDevicePose ( 0 ) ;
if ( ! pose . connected & & ! mPose . connected )
return ;
MatrixF offsetMat = getBaseTrackingTransform ( ) ;
//offsetMat.inverse();
Point3F pos = offsetMat . getPosition ( ) ;
//Con::printf("Base offs == %f,%f,%f", pos.x, pos.y, pos.z);
const F32 CONTROLLER_SCALE = 0.1 ;
if ( smDebugControllerPosition )
{
ColorI drawColor = ColorI : : GREEN ;
if ( ! pose . valid )
{
drawColor = ColorI : : RED ;
}
// Draw Camera
/*
DisplayPose cameraPose ;
OPENVR - > getFrameEyePose ( & cameraPose , - 1 ) ;
Point3F cameraCenter ( 0 ) ;
MatrixF cameraMat ( 1 ) ;
cameraPose . orientation . setMatrix ( & cameraMat ) ;
cameraMat . setPosition ( cameraPose . position ) ;
cameraMat . mulP ( cameraCenter ) ;
//DebugDrawer::get()->drawBox(cameraCenter - Point3F(0.1), cameraCenter + Point3F(0.1), ColorI::GREEN);
DebugDrawer : : get ( ) - > drawTransformedBoxOutline ( Point3F ( - 0.5 , - 0.1 , - 0.5 ) , Point3F ( 0.5 , 0.1 , 0.5 ) , ColorI : : WHITE , cameraMat ) ; // general box
*/
// Draw Tracked HMD Pos
Point3F hmdCenter ( 0 , 0 , 0 ) ;
MatrixF hmdMat ( 1 ) ;
hmdPose . orientation . setMatrix ( & hmdMat ) ;
hmdMat . setPosition ( hmdPose . position ) ;
hmdMat . inverse ( ) ; // -> world mat (as opposed to world -> tracked pos)
hmdMat = offsetMat * hmdMat ;
hmdMat . mulP ( hmdCenter ) ;
DebugDrawer : : get ( ) - > drawBox ( hmdCenter - Point3F ( 0.1 ) , hmdCenter + Point3F ( 0.1 ) , ColorI : : RED ) ;
DebugDrawer : : get ( ) - > drawTransformedBoxOutline ( Point3F ( - 0.5 , - 0.1 , - 0.5 ) , Point3F ( 0.5 , 0.1 , 0.5 ) , ColorI : : GREEN , hmdMat ) ; // general box
// Draw Controller
MatrixF mat ( 1 ) ;
pose . orientation . setMatrix ( & mat ) ;
mat . setPosition ( pose . position ) ;
mat . inverse ( ) ; // same as HMD
mat = offsetMat * mat ;
Point3F middleStart ( 0 , - 1 * CONTROLLER_SCALE , 0 ) ;
Point3F middleEnd ( 0 , 1 * CONTROLLER_SCALE , 0 ) ;
Point3F middle ( 0 , 0 , 0 ) ;
Point3F center ( 0 , 0 , 0 ) ;
mat . mulP ( center ) ;
//DebugDrawer::get()->drawBox(center - Point3F(0.1), center + Point3F(0.1), ColorI::BLUE);
mat . mulP ( middleStart ) ;
mat . mulP ( middle ) ;
mat . mulP ( middleEnd ) ;
char buffer [ 256 ] ;
dSprintf ( buffer , 256 , " %f %f %f " , center . x , center . y , center . z ) ;
DebugDrawer : : get ( ) - > drawText ( middle , buffer ) ;
DebugDrawer : : get ( ) - > drawLine ( middleStart , middle , ColorI ( 0 , 255 , 0 ) ) ; // axis back
DebugDrawer : : get ( ) - > drawLine ( middleEnd , middle , ColorI ( 255 , 0 , 0 ) ) ; // axis forward
DebugDrawer : : get ( ) - > drawTransformedBoxOutline ( Point3F ( - 0.5 , - 1 , - 0.5 ) * CONTROLLER_SCALE , Point3F ( 0.5 , 1 , 0.5 ) * CONTROLLER_SCALE , drawColor , mat ) ; // general box
DebugDrawer : : get ( ) - > drawBoxOutline ( Point3F ( - 1 ) , Point3F ( 1 ) , ColorI : : WHITE ) ;
}
if ( isClientObject ( ) & & smDebugControllerMovePosition )
{
MatrixF transform = getRenderTransform ( ) ;
transform . scale ( mObjScale ) ;
DebugDrawer : : get ( ) - > drawTransformedBoxOutline ( mObjBox . minExtents , mObjBox . maxExtents , ColorI : : RED , transform ) ;
// jamesu - grab server object pose for debugging
OpenVRTrackedObject * tracked = static_cast < OpenVRTrackedObject * > ( getServerObject ( ) ) ;
if ( tracked )
{
mPose = tracked - > mPose ;
}
ColorI drawColor = ColorI : : GREEN ;
if ( ! pose . valid )
{
drawColor = ColorI : : RED ;
}
// Draw Controller
MatrixF mat ( 1 ) ;
mPose . orientation . setMatrix ( & mat ) ;
mat . setPosition ( mPose . position ) ;
mat . inverse ( ) ; // same as HMD
mat = offsetMat * mat ;
Point3F middleStart ( 0 , - 1 * CONTROLLER_SCALE , 0 ) ;
Point3F middleEnd ( 0 , 1 * CONTROLLER_SCALE , 0 ) ;
Point3F middle ( 0 , 0 , 0 ) ;
Point3F center ( 0 , 0 , 0 ) ;
mat . mulP ( center ) ;
//DebugDrawer::get()->drawBox(center - Point3F(0.1), center + Point3F(0.1), ColorI::BLUE);
mat . mulP ( middleStart ) ;
mat . mulP ( middle ) ;
mat . mulP ( middleEnd ) ;
char buffer [ 256 ] ;
dSprintf ( buffer , 256 , " %f %f %f " , center . x , center . y , center . z ) ;
DebugDrawer : : get ( ) - > drawText ( middle , buffer ) ;
DebugDrawer : : get ( ) - > drawLine ( middleStart , middle , ColorI ( 0 , 255 , 0 ) ) ; // axis back
DebugDrawer : : get ( ) - > drawLine ( middleEnd , middle , ColorI ( 255 , 0 , 0 ) ) ; // axis forward
DebugDrawer : : get ( ) - > drawTransformedBoxOutline ( Point3F ( - 0.5 , - 1 , - 0.5 ) * CONTROLLER_SCALE , Point3F ( 0.5 , 1 , 0.5 ) * CONTROLLER_SCALE , drawColor , mat ) ; // general box
DebugDrawer : : get ( ) - > drawBoxOutline ( Point3F ( - 1 ) , Point3F ( 1 ) , ColorI : : WHITE ) ;
}
// Controller matrix base
MatrixF trackedMat = getTrackedTransform ( ) ;
MatrixF invTrackedMat ( 1 ) ;
invTrackedMat = trackedMat ;
invTrackedMat . inverse ( ) ; // -> world mat (as opposed to world -> tracked pos)
invTrackedMat = getBaseTrackingTransform ( ) * invTrackedMat ;
trackedMat = invTrackedMat ;
trackedMat . inverse ( ) ;
// Render the controllers, using either the render model or the shape
if ( mShapeInstance )
{
// Calculate the distance of this object from the camera
Point3F cameraOffset = invTrackedMat . getPosition ( ) ;
cameraOffset - = state - > getDiffuseCameraPosition ( ) ;
F32 dist = cameraOffset . len ( ) ;
if ( dist < 0.01f )
dist = 0.01f ;
// Set up the LOD for the shape
F32 invScale = ( 1.0f / getMax ( getMax ( mObjScale . x , mObjScale . y ) , mObjScale . z ) ) ;
mShapeInstance - > setDetailFromDistance ( state , dist * invScale ) ;
// Make sure we have a valid level of detail
if ( mShapeInstance - > getCurrentDetail ( ) < 0 )
return ;
// GFXTransformSaver is a handy helper class that restores
// the current GFX matrices to their original values when
// it goes out of scope at the end of the function
GFXTransformSaver saver ;
// Set up our TS render state
TSRenderState rdata ;
rdata . setSceneState ( state ) ;
rdata . setFadeOverride ( 1.0f ) ;
// We might have some forward lit materials
// so pass down a query to gather lights.
LightQuery query ;
query . init ( getWorldSphere ( ) ) ;
rdata . setLightQuery ( & query ) ;
// Set the world matrix to the objects render transform
MatrixF mat = trackedMat ;
mat . scale ( mObjScale ) ;
GFX - > setWorldMatrix ( mat ) ;
// TODO: move the nodes about for components
mShapeInstance - > animate ( ) ;
mShapeInstance - > render ( rdata ) ;
}
else if ( mRenderComponents . size ( ) > 0 )
{
vr : : IVRRenderModels * models = OPENVR - > getRenderModels ( ) ;
if ( ! models )
return ;
vr : : IVRSystem * vrs = vr : : VRSystem ( ) ;
if ( ! vrs - > GetControllerState ( mDeviceIndex , & mCurrentControllerState ) )
{
return ;
}
for ( U32 i = 0 , sz = mRenderComponents . size ( ) ; i < sz ; i + + )
{
RenderModelSlot slot = mRenderComponents [ i ] ;
vr : : RenderModel_ControllerMode_State_t modeState ;
vr : : RenderModel_ComponentState_t componentState ;
modeState . bScrollWheelVisible = false ;
if ( models - > GetComponentState ( mModelName , slot . componentName , & mCurrentControllerState , & modeState , & componentState ) )
{
MeshRenderInst * ri = renderPass - > allocInst < MeshRenderInst > ( ) ;
// Set our RenderInst as a standard mesh render
ri - > type = RenderPassManager : : RIT_Mesh ;
// Calculate our sorting point
if ( state & & slot . nativeModel )
{
// Calculate our sort point manually.
const Box3F rBox = slot . nativeModel - > getWorldBox ( invTrackedMat ) ;
ri - > sortDistSq = rBox . getSqDistanceToPoint ( state - > getCameraPosition ( ) ) ;
}
else
{
ri - > sortDistSq = 0.0f ;
}
MatrixF newTransform = trackedMat ;
MatrixF controllerOffsMat = OpenVRUtil : : convertSteamVRAffineMatrixToMatrixFPlain ( componentState . mTrackingToComponentRenderModel ) ;
MatrixF offComponentMat ( 1 ) ;
OpenVRUtil : : convertTransformFromOVR ( controllerOffsMat , offComponentMat ) ;
newTransform = offComponentMat * newTransform ;
newTransform . inverse ( ) ;
//DebugDrawer::get()->drawBox(newTransform.getPosition() - Point3F(0.001), newTransform.getPosition() + Point3F(0.001), ColorI::BLUE);
if ( ! slot . nativeModel )
continue ;
if ( i < 1 )
continue ;
// Set up our transforms
ri - > objectToWorld = renderPass - > allocUniqueXform ( newTransform ) ;
ri - > worldToCamera = renderPass - > allocSharedXform ( RenderPassManager : : View ) ;
ri - > projection = renderPass - > allocSharedXform ( RenderPassManager : : Projection ) ;
// If our material needs lights then fill the RIs
// light vector with the best lights.
if ( true )
{
LightQuery query ;
Point3F center ( 0 , 0 , 0 ) ;
invTrackedMat . mulP ( center ) ;
query . init ( SphereF ( center , 10.0f ) ) ;
query . getLights ( ri - > lights , 8 ) ;
}
// Draw model
slot . nativeModel - > draw ( state , ri ) ;
state - > getRenderPass ( ) - > addInst ( ri ) ;
}
}
}
else if ( mBasicModel )
{
MeshRenderInst * ri = renderPass - > allocInst < MeshRenderInst > ( ) ;
// Set our RenderInst as a standard mesh render
ri - > type = RenderPassManager : : RIT_Mesh ;
// Calculate our sorting point
if ( state )
{
// Calculate our sort point manually.
const Box3F rBox = mBasicModel - > getWorldBox ( invTrackedMat ) ;
ri - > sortDistSq = rBox . getSqDistanceToPoint ( state - > getCameraPosition ( ) ) ;
}
else
{
ri - > sortDistSq = 0.0f ;
}
MatrixF newTransform = invTrackedMat ;
// Set up our transforms
ri - > objectToWorld = renderPass - > allocUniqueXform ( newTransform ) ;
ri - > worldToCamera = renderPass - > allocSharedXform ( RenderPassManager : : View ) ;
ri - > projection = renderPass - > allocSharedXform ( RenderPassManager : : Projection ) ;
// If our material needs lights then fill the RIs
// light vector with the best lights.
if ( true )
{
LightQuery query ;
Point3F center ( 0 , 0 , 0 ) ;
invTrackedMat . mulP ( center ) ;
query . init ( SphereF ( center , 10.0f ) ) ;
query . getLights ( ri - > lights , 8 ) ;
}
// Draw model
mBasicModel - > draw ( state , ri ) ;
state - > getRenderPass ( ) - > addInst ( ri ) ;
}
2016-06-14 23:12:27 +00:00
}
U32 OpenVRTrackedObject : : getCollisionMask ( )
{
2016-07-12 22:30:11 +00:00
if ( isServerObject ( ) )
return sServerCollisionMask ;
else
return sClientCollisionMask ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : updateWorkingCollisionSet ( )
{
2016-07-12 22:30:11 +00:00
const U32 mask = getCollisionMask ( ) ;
Box3F convexBox = mConvexList - > getBoundingBox ( getTransform ( ) , getScale ( ) ) ;
F32 len = ( 50 ) * TickSec ;
F32 l = ( len * 1.1 ) + 0.1 ; // fudge factor
convexBox . minExtents - = Point3F ( l , l , l ) ;
convexBox . maxExtents + = Point3F ( l , l , l ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
disableCollision ( ) ;
mConvexList - > updateWorkingList ( convexBox , mask ) ;
enableCollision ( ) ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : updateMove ( const Move * move )
{
2016-07-12 22:30:11 +00:00
// Set transform based on move
2016-06-14 23:12:27 +00:00
# ifdef TORQUE_EXTENDED_MOVE
2016-07-12 22:30:11 +00:00
const ExtendedMove * emove = dynamic_cast < const ExtendedMove * > ( move ) ;
if ( ! emove )
return ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
U32 emoveIndex = mMappedMoveIndex ;
if ( emoveIndex > = ExtendedMove : : MaxPositionsRotations )
emoveIndex = 0 ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
//IDevicePose pose = OPENVR->getTrackedDevicePose(mDeviceIndex);
//Con::printf("OpenVRTrackedObject::processTick move %i", emoveIndex);
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
if ( ! emove - > EulerBasedRotation [ emoveIndex ] )
{
AngAxisF inRot = AngAxisF ( Point3F ( emove - > rotX [ emoveIndex ] , emove - > rotY [ emoveIndex ] , emove - > rotZ [ emoveIndex ] ) , emove - > rotW [ emoveIndex ] ) ;
// Update our pose based on the move info
mPose . orientation = inRot ;
mPose . position = Point3F ( emove - > posX [ emoveIndex ] , emove - > posY [ emoveIndex ] , emove - > posZ [ emoveIndex ] ) ;
mPose . valid = true ;
mPose . connected = true ;
}
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
// Set transform based on move pose
MatrixF trackedMat ( 1 ) ;
MatrixF invTrackedMat ( 1 ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
mPose . orientation . setMatrix ( & trackedMat ) ;
trackedMat . setPosition ( mPose . position ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
invTrackedMat = trackedMat ;
invTrackedMat . inverse ( ) ; // -> world mat (as opposed to world -> tracked pos)
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
invTrackedMat = getBaseTrackingTransform ( ) * invTrackedMat ;
trackedMat = invTrackedMat ;
trackedMat . inverse ( ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
SceneObject : : setTransform ( invTrackedMat ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
if ( mPhysicsRep )
mPhysicsRep - > setTransform ( invTrackedMat ) ;
2016-06-14 23:12:27 +00:00
# endif
}
void OpenVRTrackedObject : : processTick ( const Move * move )
{
2016-07-12 22:30:11 +00:00
// Perform collision checks
if ( isServerObject ( ) )
{
updateMove ( move ) ;
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
if ( ! mPhysicsRep )
{
updateWorkingCollisionSet ( ) ;
}
}
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
Parent : : processTick ( move ) ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : interpolateTick ( F32 delta )
{
2016-07-12 22:30:11 +00:00
// Set latest transform
2016-06-14 23:12:27 +00:00
2016-07-12 22:30:11 +00:00
Parent : : interpolateTick ( delta ) ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : advanceTime ( F32 dt )
{
2016-07-12 22:30:11 +00:00
Parent : : advanceTime ( dt ) ;
2016-06-14 23:12:27 +00:00
}
bool OpenVRTrackedObject : : castRay ( const Point3F & start , const Point3F & end , RayInfo * info )
{
2016-07-12 22:30:11 +00:00
if ( ! mPose . connected | | ! mPose . valid )
return false ;
// Collide against bounding box.
F32 st , et , fst = 0.0f , fet = 1.0f ;
F32 * bmin = & mObjBox . minExtents . x ;
F32 * bmax = & mObjBox . maxExtents . x ;
F32 const * si = & start . x ;
F32 const * ei = & end . x ;
for ( S32 i = 0 ; i < 3 ; i + + ) {
if ( * si < * ei ) {
if ( * si > * bmax | | * ei < * bmin )
return false ;
F32 di = * ei - * si ;
st = ( * si < * bmin ) ? ( * bmin - * si ) / di : 0.0f ;
et = ( * ei > * bmax ) ? ( * bmax - * si ) / di : 1.0f ;
}
else {
if ( * ei > * bmax | | * si < * bmin )
return false ;
F32 di = * ei - * si ;
st = ( * si > * bmax ) ? ( * bmax - * si ) / di : 0.0f ;
et = ( * ei < * bmin ) ? ( * bmin - * si ) / di : 1.0f ;
}
if ( st > fst ) fst = st ;
if ( et < fet ) fet = et ;
if ( fet < fst )
return false ;
bmin + + ; bmax + + ;
si + + ; ei + + ;
}
info - > normal = start - end ;
info - > normal . normalizeSafe ( ) ;
getTransform ( ) . mulV ( info - > normal ) ;
info - > t = fst ;
info - > object = this ;
info - > point . interpolate ( start , end , fst ) ;
info - > material = 0 ;
return true ;
2016-06-14 23:12:27 +00:00
}
void OpenVRTrackedObject : : buildConvex ( const Box3F & box , Convex * convex )
{
2016-07-12 22:30:11 +00:00
// These should really come out of a pool
mConvexList - > collectGarbage ( ) ;
Box3F realBox = box ;
mWorldToObj . mul ( realBox ) ;
realBox . minExtents . convolveInverse ( mObjScale ) ;
realBox . maxExtents . convolveInverse ( mObjScale ) ;
if ( realBox . isOverlapped ( getObjBox ( ) ) = = false )
return ;
// Just return a box convex for the entire shape...
Convex * cc = 0 ;
CollisionWorkingList & wl = convex - > getWorkingList ( ) ;
for ( CollisionWorkingList * itr = wl . wLink . mNext ; itr ! = & wl ; itr = itr - > wLink . mNext ) {
if ( itr - > mConvex - > getType ( ) = = BoxConvexType & &
itr - > mConvex - > getObject ( ) = = this ) {
cc = itr - > mConvex ;
break ;
}
}
if ( cc )
return ;
// Create a new convex.
BoxConvex * cp = new BoxConvex ;
mConvexList - > registerObject ( cp ) ;
convex - > addToWorkingList ( cp ) ;
cp - > init ( this ) ;
mObjBox . getCenter ( & cp - > mCenter ) ;
cp - > mSize . x = mObjBox . len_x ( ) / 2.0f ;
cp - > mSize . y = mObjBox . len_y ( ) / 2.0f ;
cp - > mSize . z = mObjBox . len_z ( ) / 2.0f ;
2016-06-14 23:12:27 +00:00
}
bool OpenVRTrackedObject : : testObject ( SceneObject * enter )
{
2016-07-12 22:30:11 +00:00
return false ; // TODO
2016-06-14 23:12:27 +00:00
}
DefineEngineMethod ( OpenVRTrackedObject , setModelName , void , ( String modelName ) , , " Set model name. Typically you should do this from the client to update the server representation. " )
{
2016-07-12 22:30:11 +00:00
object - > setModelName ( modelName ) ;
2016-06-14 23:12:27 +00:00
}