So, I have this code where I can "glue" a sphere to a cube, and unglue it too:
// Project: testing_medium
// Created: 2018-02-17
// show all errors
SetErrorMode(2)
//Load the AGKVR plugin
#import_plugin AGKVR
// set window properties
SetWindowTitle( "move object" )
SetSyncRate(0, 0)
SetWindowSize( 1024, 768, 0 )
SetScissor(0, 0, 0, 0)
UseNewDefaultFonts( 1 )
SetPrintSize( 10 )
SetPrintColor( 255,0,0 )
SetGenerateMipmaps( 0 )
SetAntialiasMode( 1 ) // 0=off, 1=4xMSAA
SetDefaultMagFilter( 1 ) // 0=nearest, 1=linear
SetDefaultMinFilter( 1 ) // 0=nearest, 1=linear
Create3DPhysicsWorld(1) //Setup Physics
Set3DPhysicsGravity ( 0.0, 0.0, 0.0 )
/*===============================================================================
VR TECH STUFFIE
===============================================================================*/
//Set the Camera Range in AGKVR
//It is necessary to use this command for setting the camera's range instead of the standard AGK SetCameraRange command
//AGKVR.SetCameraRange( 0.01, 1000.0 )
AGKVR.SetCameraRange( 0.005, 100.0 )
//Initialiaze AGKVR
// The parameters are the Right and Left Eye image ID's that will be used to render to the HMD
InitError As Integer
RightEyeImg As Integer = 500
LeftEyeImg As Integer = 501
InitError = AGKVR.Init( RightEyeImg, LeftEyeImg )
// InitError = 0: SUCCESS!
// InitError = 1: Unable to init VR runtime
// InitError = 2: Compositor initialization failed.
//This command will lock the player's heading direction
//to follow the turn angle of the HMD. This would be common in FPS games, where
//you want the forward moving direction's turn angle to change based on where the
//player is looking. LockPlayerTurn is ON(1) by default
AGKVR.LockPlayerTurn( 1 )
//This command will lock the player's heading direction (forward on the Z axis)
//to follow the pitch angle of the HMD. This would be useful in a freeflight style game
//where you want the forward moving direction's pitch angle to change based on where the
//player is looking. LockPlayerPitch is OFF(0) by default
AGKVR.LockPlayerPitch( 0 )
#constant FALSE = 0
#constant TRUE = 1
// Create world
// ----------------------------------------------------------------
SetGenerateMipmaps( 0 )
SetClearColor (128,128,128)
SetSunActive (1)
SetSunColor( 200, 280, 200 )
SunVx#= 0.2 // -0.3714
SunVy#= -0.2 // -0.7428
SunVz#= -1 // 0.5571
SetSunDirection( SunVx#, SunVy#, SunVz#)
SetAmbientColor( 0,0,0 )
SetShadowMappingMode( 3 )
// 0 = turn it off
// 1 = Uniform shadows (lower but consistent quality.)
// 2 = LiPSM shadows (Light Space Perspective shadow mapping (LiPSM) which has higher quality in most cases)
// 3 = Cascade shadow (high quality near the camera whilst still allowing lower quality shadows in the distance.)
SetShadowSmoothing( 1 )
// 0 = no smoothing --- no gradients
// 1 = multismapling --- pixelated gradients
// 2 = random multisampling --- gradients smoothed with shimering noise
SetShadowMapSize( 2048, 2048 ) // Higher equals better quality shadows
SetShadowRange( 5 ) // -1 to use the full camera range
SetShadowBias( 0.0012 ) // offset shadows slightly to avoid shadow artifacts
Global littleBall
littleBall = CreateObjectSphere (0.25, 32, 32)
SetObjectPosition( littleBall, 0.6, 1.5, 0.6 )
Create3DPhysicsStaticBody(littleBall)
SetObjectCollisionMode( littleBall, 1 ) //On
SetObjectShapeSphere( littleBall, 0.25 )
SetObjectCullMode( littleBall, 0 ) // 0 draws backfaces too
SetObjectColor (littleBall, 167, 255, 237, 25 )
SetObjectTransparency( littleBall, 1 )
A_down as integer = FALSE
B_down as integer = FALSE
Global fixedThing as integer = FALSE
Global rightControllerObject
rightControllerObject = CreateObjectBox (0.03, 0.03, 0.03)
SetObjectColor(rightControllerObject, 0, 255, 255, 255)
Create3DPhysicsStaticBody(rightControllerObject)
distance as Float
Global touchedObject = 0
do
SetObjectPosition( rightControllerObject, AGKVR.GetRightHandX(), AGKVR.GetRightHandY(), AGKVR.GetRightHandZ())
SetObjectRotation( rightControllerObject, AGKVR.GetRightHandAngleX(), AGKVR.GetRightHandAngleY(), AGKVR.GetRightHandAngleZ() )
if fixedThing = FALSE and A_down = FALSE and AGKVR.RightController_Button2() = TRUE // Button A
// parent is rightControllerObject, child is littleBall
rotw# = GetObjectQuatW(rightControllerObject)
rotx# = GetObjectQuatX(rightControllerObject)
roty# = GetObjectQuatY(rightControllerObject)
rotz# = GetObjectQuatZ(rightControllerObject)
posx# = GetObjectX(rightControllerObject)
posy# = GetObjectY(rightControllerObject)
posz# = GetObjectZ(rightControllerObject)
// use rightControllerObject to do the inverse transform
SetObjectPosition( rightControllerObject, 0,0,0 )
SetObjectRotationQuat( rightControllerObject, -rotw#, rotx#, roty#, rotz# )
// use littleBall to do the forward transform
SetObjectPosition( littleBall, GetObjectX(littleBall)-posx#, GetObjectY(littleBall)-posy#, GetObjectZ(littleBall)-posz# )
FixObjectToObject(littleBall,rightControllerObject)
// the world coordinates combine the two transforms
newx# = GetObjectWorldX( littleBall )
newy# = GetObjectWorldY( littleBall )
newz# = GetObjectWorldZ( littleBall )
newrotw# = GetObjectWorldQuatW( littleBall )
newrotx# = GetObjectWorldQuatX( littleBall )
newroty# = GetObjectWorldQuatY( littleBall )
newrotz# = GetObjectWorldQuatZ( littleBall )
// set littleBall to use the new transform
SetObjectPosition( littleBall, newx#, newy#, newz# )
SetObjectRotationQuat( littleBall, newrotw#, newrotx#, newroty#, newrotz# )
// reset rightControllerObject back to where it was
SetObjectPosition( rightControllerObject, posx#, posy#, posz# )
SetObjectRotationQuat( rightControllerObject, rotw#, rotx#, roty#, rotz# )
fixedThing = TRUE
A_down = TRUE
elseif AGKVR.RightController_Button2() = FALSE
A_down = FALSE
endif
if fixedThing = TRUE and A_down = FALSE and AGKVR.RightController_Button2() = TRUE // Button B
funPosX# = GetObjectWorldX(littleBall)
funPosY# = GetObjectWorldY(littleBall)
funPosZ# = GetObjectWorldZ(littleBall)
funRotX# = GetObjectWorldAngleX(littleBall)
funRotY# = GetObjectWorldAngleY(littleBall)
funRotZ# = GetObjectWorldAngleZ(littleBall)
FixObjectToObject(littleBall, 0)
setObjectPosition( littleBall, funPosX#, funPosY#, funPosZ# )
SetObjectRotation( littleBall, funRotX#, funRotY#, funRotZ# )
fixedThing = FALSE
A_down = TRUE
elseif AGKVR.RightController_Button2() = FALSE
A_down = FALSE
endif
Step3DPhysicsWorld()
/*===============================================================================
RENDER TO VR
===============================================================================*/
AGKVR.UpdatePlayer( )
AGKVR.Render( )
/*===============================================================================
AIM SCREEN CAMERA
===============================================================================*/
// The camera's position and rotation will determine what is displayed on the monitor, not the HMD
SetCameraPosition( 1, AGKVR.GetHMDX(), AGKVR.GetHMDY(), AGKVR.GetHMDZ())
SetCameraRotation( 1, AGKVR.GetHMDAngleX(), AGKVR.GetHMDAngleY(), AGKVR.GetHMDAngleZ())
Sync()
loop
But I want to not just glue the sphere to the cube, but any object that the cube gets in contact with.
So I use ObjectSphereCast() to detect whatever object is in contact with the cube:
ObjectSphereCast( 0, AGKVR.GetRightHandX()-0.01, AGKVR.GetRightHandY()-0.01, AGKVR.GetRightHandZ()-0.01, AGKVR.GetRightHandX()+0.01, AGKVR.GetRightHandY()+0.01, AGKVR.GetRightHandZ()+0.01, 0.02)
if GetObjectRayCastNumHits() = TRUE // if an object is currently being hit ...
touchedObject = GetObjectRayCastHitID(0)
...But now, the object in contact with the cube (which is the same old sphere) suddenly gets positioned several meters away. It seems like I'm getting some wrong values. I think I had been in this mess before where it was something with getting the parents value or something. Anyway, my misbehaving code goes like this:
// show all errors
SetErrorMode(2)
//Load the AGKVR plugin
#import_plugin AGKVR
// set window properties
SetWindowTitle( "move object on touch" )
SetSyncRate(0, 0)
SetWindowSize( 1024, 768, 0 )
SetScissor(0, 0, 0, 0)
UseNewDefaultFonts( 1 )
SetPrintSize( 10 )
SetPrintColor( 255,0,0 )
SetGenerateMipmaps( 0 )
SetAntialiasMode( 1 ) // 0=off, 1=4xMSAA
SetDefaultMagFilter( 1 ) // 0=nearest, 1=linear
SetDefaultMinFilter( 1 ) // 0=nearest, 1=linear
Create3DPhysicsWorld(1) //Setup Physics
Set3DPhysicsGravity ( 0.0, 0.0, 0.0 )
/*===============================================================================
VR TECH STUFFIE
===============================================================================*/
//Set the Camera Range in AGKVR
//It is necessary to use this command for setting the camera's range instead of the standard AGK SetCameraRange command
//AGKVR.SetCameraRange( 0.01, 1000.0 )
AGKVR.SetCameraRange( 0.005, 100.0 )
//Initialiaze AGKVR
// The parameters are the Right and Left Eye image ID's that will be used to render to the HMD
InitError As Integer
RightEyeImg As Integer = 500
LeftEyeImg As Integer = 501
InitError = AGKVR.Init( RightEyeImg, LeftEyeImg )
// InitError = 0: SUCCESS!
// InitError = 1: Unable to init VR runtime
// InitError = 2: Compositor initialization failed.
//This command will lock the player's heading direction
//to follow the turn angle of the HMD. This would be common in FPS games, where
//you want the forward moving direction's turn angle to change based on where the
//player is looking. LockPlayerTurn is ON(1) by default
AGKVR.LockPlayerTurn( 1 )
//This command will lock the player's heading direction (forward on the Z axis)
//to follow the pitch angle of the HMD. This would be useful in a freeflight style game
//where you want the forward moving direction's pitch angle to change based on where the
//player is looking. LockPlayerPitch is OFF(0) by default
AGKVR.LockPlayerPitch( 0 )
#constant FALSE = 0
#constant TRUE = 1
// Create world
// ----------------------------------------------------------------
SetGenerateMipmaps( 0 )
SetClearColor (128,128,128)
SetSunActive (1)
SetSunColor( 200, 280, 200 )
SunVx#= 0.2 // -0.3714
SunVy#= -0.2 // -0.7428
SunVz#= -1 // 0.5571
SetSunDirection( SunVx#, SunVy#, SunVz#)
SetAmbientColor( 0,0,0 )
SetShadowMappingMode( 3 )
// 0 = turn it off
// 1 = Uniform shadows (lower but consistent quality.)
// 2 = LiPSM shadows (Light Space Perspective shadow mapping (LiPSM) which has higher quality in most cases)
// 3 = Cascade shadow (high quality near the camera whilst still allowing lower quality shadows in the distance.)
SetShadowSmoothing( 1 )
// 0 = no smoothing --- no gradients
// 1 = multismapling --- pixelated gradients
// 2 = random multisampling --- gradients smoothed with shimering noise
SetShadowMapSize( 2048, 2048 ) // Higher equals better quality shadows
SetShadowRange( 5 ) // -1 to use the full camera range
SetShadowBias( 0.0012 ) // offset shadows slightly to avoid shadow artifacts
Global littleBall
littleBall = CreateObjectSphere (0.25, 32, 32)
SetObjectPosition( littleBall, 0.6, 1.5, 0.6 )
Create3DPhysicsStaticBody(littleBall)
SetObjectCollisionMode( littleBall, 1 ) //On
SetObjectShapeSphere( littleBall, 0.25 )
SetObjectCullMode( littleBall, 0 ) // 0 draws backfaces too
SetObjectColor (littleBall, 167, 255, 237, 25 )
SetObjectTransparency( littleBall, 1 )
A_down as integer = FALSE
B_down as integer = FALSE
Global fixedThing as integer = FALSE
Global rightControllerObject
rightControllerObject = CreateObjectBox (0.03, 0.03, 0.03)
SetObjectColor(rightControllerObject, 0, 255, 255, 255)
Create3DPhysicsStaticBody(rightControllerObject)
distance as Float
Global touchedObject = 0
do
// Hide the controller so we don't hit it:
SetObjectPosition( rightControllerObject, 0, 0, 0)
if fixedThing = FALSE and A_down = FALSE and AGKVR.RightController_Button2() = TRUE // Button A
ObjectSphereCast( 0, AGKVR.GetRightHandX()-0.01, AGKVR.GetRightHandY()-0.01, AGKVR.GetRightHandZ()-0.01, AGKVR.GetRightHandX()+0.01, AGKVR.GetRightHandY()+0.01, AGKVR.GetRightHandZ()+0.01, 0.02)
if GetObjectRayCastNumHits() = TRUE // if an object is currently being hit ...
touchedObject = GetObjectRayCastHitID(0)
// parent is rightControllerObject, child is touchedObject
rotw# = GetObjectQuatW(rightControllerObject)
rotx# = GetObjectQuatX(rightControllerObject)
roty# = GetObjectQuatY(rightControllerObject)
rotz# = GetObjectQuatZ(rightControllerObject)
posx# = GetObjectX(rightControllerObject)
posy# = GetObjectY(rightControllerObject)
posz# = GetObjectZ(rightControllerObject)
// use rightControllerObject to do the inverse transform
SetObjectPosition( rightControllerObject, 0,0,0 )
SetObjectRotationQuat( rightControllerObject, -rotw#, rotx#, roty#, rotz# )
// use touchedObject to do the forward transform
SetObjectPosition( touchedObject, GetObjectX(touchedObject)-posx#, GetObjectY(touchedObject)-posy#, GetObjectZ(touchedObject)-posz# )
FixObjectToObject(touchedObject,rightControllerObject)
// the world coordinates combine the two transforms
newx# = GetObjectWorldX( touchedObject )
newy# = GetObjectWorldY( touchedObject )
newz# = GetObjectWorldZ( touchedObject )
newrotw# = GetObjectWorldQuatW( touchedObject )
newrotx# = GetObjectWorldQuatX( touchedObject )
newroty# = GetObjectWorldQuatY( touchedObject )
newrotz# = GetObjectWorldQuatZ( touchedObject )
// set touchedObject to use the new transform
SetObjectPosition( touchedObject, newx#, newy#, newz# )
SetObjectRotationQuat( touchedObject, newrotw#, newrotx#, newroty#, newrotz# )
// reset rightControllerObject back to where it was
SetObjectPosition( rightControllerObject, posx#, posy#, posz# )
SetObjectRotationQuat( rightControllerObject, rotw#, rotx#, roty#, rotz# )
fixedThing = TRUE
A_down = TRUE
endif
elseif AGKVR.RightController_Button2() = FALSE
A_down = FALSE
endif
if fixedThing = TRUE and A_down = FALSE and AGKVR.RightController_Button2() = TRUE // Button B
funPosX# = GetObjectWorldX(touchedObject)
funPosY# = GetObjectWorldY(touchedObject)
funPosZ# = GetObjectWorldZ(touchedObject)
funRotX# = GetObjectWorldAngleX(touchedObject)
funRotY# = GetObjectWorldAngleY(touchedObject)
funRotZ# = GetObjectWorldAngleZ(touchedObject)
FixObjectToObject(touchedObject, 0)
setObjectPosition( touchedObject, funPosX#, funPosY#, funPosZ# )
SetObjectRotation( touchedObject, funRotX#, funRotY#, funRotZ# )
fixedThing = FALSE
A_down = TRUE
elseif AGKVR.RightController_Button2() = FALSE
A_down = FALSE
endif
// show the controller
SetObjectPosition( rightControllerObject, AGKVR.GetRightHandX(), AGKVR.GetRightHandY(), AGKVR.GetRightHandZ())
SetObjectRotation( rightControllerObject, AGKVR.GetRightHandAngleX(), AGKVR.GetRightHandAngleY(), AGKVR.GetRightHandAngleZ() )
Step3DPhysicsWorld()
/*===============================================================================
RENDER TO VR
===============================================================================*/
AGKVR.UpdatePlayer( )
AGKVR.Render( )
/*===============================================================================
AIM SCREEN CAMERA
===============================================================================*/
// The camera's position and rotation will determine what is displayed on the monitor, not the HMD
SetCameraPosition( 1, AGKVR.GetHMDX(), AGKVR.GetHMDY(), AGKVR.GetHMDZ())
SetCameraRotation( 1, AGKVR.GetHMDAngleX(), AGKVR.GetHMDAngleY(), AGKVR.GetHMDAngleZ())
Sync()
loop