Added Unity project files
This commit is contained in:
127
Packages/com.vrchat.worlds/Runtime/VRCSDK/PhysBoneGrabHelper.cs
Normal file
127
Packages/com.vrchat.worlds/Runtime/VRCSDK/PhysBoneGrabHelper.cs
Normal file
@ -0,0 +1,127 @@
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
using VRC.Dynamics;
|
||||
|
||||
namespace VRC.SDK3.Dynamics.PhysBone
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal component that makes it possible to grab and pose PhysBones for testing in an SDK project while it's
|
||||
/// in play mode.
|
||||
/// </summary>
|
||||
// This component is intentionally duplicated across SDKs instead of existing in the base SDK only, to address
|
||||
// compatibility issues with community made tooling.
|
||||
[AddComponentMenu("")]
|
||||
public class PhysBoneGrabHelper : MonoBehaviour
|
||||
{
|
||||
Camera currentCamera;
|
||||
|
||||
void Update()
|
||||
{
|
||||
currentCamera = FindCamera();
|
||||
|
||||
//Process mouse input
|
||||
SetMouseDown(Input.GetMouseButton(0));
|
||||
if (mouseIsDown && Input.GetMouseButtonDown(1))
|
||||
{
|
||||
if(grab != null)
|
||||
{
|
||||
PhysBoneManager.Inst.ReleaseGrab(grab, true);
|
||||
grab = null;
|
||||
}
|
||||
}
|
||||
UpdateGrab();
|
||||
}
|
||||
|
||||
Camera FindCamera()
|
||||
{
|
||||
//Get target display
|
||||
int targetDisplay = Display.activeEditorGameViewTarget;
|
||||
|
||||
//Find camera with matching target
|
||||
Camera result = null;
|
||||
var cameras = Camera.allCameras;
|
||||
foreach(var camera in cameras) //Get the last active camera
|
||||
{
|
||||
if (camera.isActiveAndEnabled &&
|
||||
camera.cameraType == CameraType.Game &&
|
||||
camera.targetDisplay == targetDisplay &&
|
||||
camera.targetTexture == null
|
||||
)
|
||||
result = camera;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool mouseIsDown = false;
|
||||
PhysBoneManager.Grab grab;
|
||||
Vector3 grabOriginLocal;
|
||||
void SetMouseDown(bool state)
|
||||
{
|
||||
if (state == mouseIsDown)
|
||||
return;
|
||||
|
||||
mouseIsDown = state;
|
||||
|
||||
if (mouseIsDown && currentCamera != null)
|
||||
{
|
||||
var localPlayer = VRC.SDKBase.Networking.LocalPlayer;
|
||||
var playerId = localPlayer != null && localPlayer.IsValid() ? localPlayer.playerId : -1;
|
||||
var ray = GetMouseRay();
|
||||
grab = PhysBoneManager.Inst.AttemptGrab(playerId, ray, out Vector3 grabOrigin);
|
||||
if (grab != null)
|
||||
{
|
||||
grabOriginLocal = currentCamera.transform.InverseTransformPoint(grabOrigin);
|
||||
#if VERBOSE_LOGGING
|
||||
Debug.Log($"Grabbing - Chain:{grab.chainId} Bone:{grab.bone}");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (grab != null)
|
||||
{
|
||||
PhysBoneManager.Inst.ReleaseGrab(grab);
|
||||
grab = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ray GetMouseRay()
|
||||
{
|
||||
return currentCamera.ScreenPointToRay(Input.mousePosition);
|
||||
}
|
||||
void UpdateGrab()
|
||||
{
|
||||
if(currentCamera == null)
|
||||
return;
|
||||
|
||||
if (grab != null)
|
||||
{
|
||||
Vector3 curGrabOrigin = currentCamera.transform.TransformPoint(grabOriginLocal);
|
||||
var ray = GetMouseRay();
|
||||
Vector3 hit;
|
||||
if (PlaneLineIntersection(curGrabOrigin, -currentCamera.transform.forward, ray.origin, ray.origin + ray.direction * 1000f, out hit))
|
||||
{
|
||||
grab.GlobalPosition = hit + grab.LocalOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
public static bool PlaneLineIntersection(Vector3 planeOrigin, Vector3 planeNormal, Vector3 lineA, Vector3 lineB, out Vector3 hit)
|
||||
{
|
||||
float delta;
|
||||
|
||||
//Make sure the line is not parallel
|
||||
delta = Vector3.Dot(planeNormal, (lineB - lineA) - planeOrigin);
|
||||
if (delta == 0.0f)
|
||||
{
|
||||
hit = Vector3.zero;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Find the delta
|
||||
delta = Vector3.Dot(planeNormal, lineA - planeOrigin) / delta;
|
||||
hit = lineA + ((lineB - lineA) * -delta);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user