Skip to content

Commit 2593d93

Browse files
committed
Relative joints poses. Support switching between hands and controllers.
1 parent b946fca commit 2593d93

File tree

11 files changed

+105
-65
lines changed

11 files changed

+105
-65
lines changed

Assets/WebGLTemplates/WebXR/webxr.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
this.controllerB = new XRControllerData();
1313
this.handLeft = new XRHandData();
1414
this.handRight = new XRHandData();
15+
this.frameNumber = 0;
1516
this.xrData = null;
1617
}
1718

1819
function XRControllerData() {
20+
this.frame = 0;
1921
// TODO: set enabled 0 if controller was enable and then disable
2022
this.enabled = 0;
2123
this.hand = 0;
@@ -39,6 +41,7 @@
3941
}
4042

4143
function XRHandData() {
44+
this.frame = 0;
4245
// TODO: set enabled 0 if hand was enable and then disable
4346
this.enabled = 0;
4447
this.hand = 0;
@@ -356,6 +359,14 @@
356359
}
357360

358361
XRManager.prototype.getXRControllersData = function(frame, inputSources, refSpace, xrData) {
362+
xrData.handLeft.enabled = 0;
363+
xrData.handRight.enabled = 0;
364+
xrData.controllerA.enabled = 0;
365+
xrData.controllerB.enabled = 0;
366+
xrData.handLeft.frame = xrData.frameNumber;
367+
xrData.handRight.frame = xrData.frameNumber;
368+
xrData.controllerA.frame = xrData.frameNumber;
369+
xrData.controllerB.frame = xrData.frameNumber;
359370
if (!inputSources || !inputSources.length) {
360371
return;
361372
}
@@ -569,6 +580,7 @@
569580
}
570581

571582
var xrData = this.xrData;
583+
xrData.frameNumber++;
572584

573585
for (let view of pose.views) {
574586
if (view.eye === 'left') {

Assets/WebXR/Plugins/WebGL/webxr.jslib

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ mergeInto(LibraryManager.library, {
3131
var data = evt.detail;
3232
var index = 0;
3333
Object.keys(data).forEach(function (key, i) {
34+
ControllersArray[index++] = data[key].frame;
3435
ControllersArray[index++] = data[key].enabled;
3536
ControllersArray[index++] = data[key].hand;
3637
ControllersArray[index++] = data[key].positionX;
@@ -56,6 +57,7 @@ mergeInto(LibraryManager.library, {
5657
var data = evt.detail;
5758
var index = 0;
5859
Object.keys(data).forEach(function (key, i) {
60+
HandsArray[index++] = data[key].frame;
5961
HandsArray[index++] = data[key].enabled;
6062
HandsArray[index++] = data[key].hand;
6163
for (var j = 0; j < 25; j++) {

Assets/WebXR/Samples/Desert/Prefabs/Cube.prefab

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ GameObject:
1111
- component: {fileID: 8513787482403080262}
1212
- component: {fileID: 7408311752882702317}
1313
- component: {fileID: 99441339568455309}
14-
- component: {fileID: 198303582149867540}
15-
- component: {fileID: -766105182191756829}
1614
m_Layer: 0
1715
m_Name: Cube
1816
m_TagString: Untagged
@@ -60,7 +58,7 @@ MeshRenderer:
6058
m_RenderingLayerMask: 1
6159
m_RendererPriority: 0
6260
m_Materials:
63-
- {fileID: 10303, guid: 0000000000000000f000000000000000, type: 0}
61+
- {fileID: 2100000, guid: cf55eb157040bca49b365493c72ed650, type: 2}
6462
m_StaticBatchInfo:
6563
firstSubMesh: 0
6664
subMeshCount: 0
@@ -81,32 +79,3 @@ MeshRenderer:
8179
m_SortingLayerID: 0
8280
m_SortingLayer: 0
8381
m_SortingOrder: 0
84-
--- !u!65 &198303582149867540
85-
BoxCollider:
86-
m_ObjectHideFlags: 0
87-
m_CorrespondingSourceObject: {fileID: 0}
88-
m_PrefabInstance: {fileID: 0}
89-
m_PrefabAsset: {fileID: 0}
90-
m_GameObject: {fileID: 8362309011548659104}
91-
m_Material: {fileID: 0}
92-
m_IsTrigger: 0
93-
m_Enabled: 1
94-
serializedVersion: 2
95-
m_Size: {x: 1, y: 1, z: 1}
96-
m_Center: {x: 0, y: 0, z: 0}
97-
--- !u!54 &-766105182191756829
98-
Rigidbody:
99-
m_ObjectHideFlags: 0
100-
m_CorrespondingSourceObject: {fileID: 0}
101-
m_PrefabInstance: {fileID: 0}
102-
m_PrefabAsset: {fileID: 0}
103-
m_GameObject: {fileID: 8362309011548659104}
104-
serializedVersion: 2
105-
m_Mass: 1
106-
m_Drag: 0
107-
m_AngularDrag: 0.05
108-
m_UseGravity: 1
109-
m_IsKinematic: 0
110-
m_Interpolate: 0
111-
m_Constraints: 0
112-
m_CollisionDetection: 0

Assets/WebXR/Samples/Desert/Prefabs/WebXRCameraSet.prefab

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ GameObject:
937937
- component: {fileID: 4545079059221816}
938938
- component: {fileID: 114038308936181916}
939939
m_Layer: 0
940-
m_Name: WebVRCameraSet
940+
m_Name: WebXRCameraSet
941941
m_TagString: Untagged
942942
m_Icon: {fileID: 0}
943943
m_NavMeshLayer: 0
@@ -1374,6 +1374,8 @@ MonoBehaviour:
13741374
simulate3dof: 0
13751375
eyesToElbow: {x: 0.1, y: -0.4, z: 0.15}
13761376
elbowHand: {x: 0, y: 0, z: 0.25}
1377+
handJointPrefab: {fileID: 8513787482403080262, guid: 67541c9d1fd5e2c4798986ee73c07923,
1378+
type: 3}
13771379
showGOs:
13781380
- {fileID: 1136128897566686}
13791381
- {fileID: 1664295426898042}
@@ -1825,6 +1827,8 @@ MonoBehaviour:
18251827
simulate3dof: 0
18261828
eyesToElbow: {x: 0.1, y: -0.4, z: 0.15}
18271829
elbowHand: {x: 0, y: 0, z: 0.25}
1830+
handJointPrefab: {fileID: 8513787482403080262, guid: 67541c9d1fd5e2c4798986ee73c07923,
1831+
type: 3}
18281832
showGOs:
18291833
- {fileID: 1644997114004198}
18301834
- {fileID: 1091283458777958}

Assets/WebXR/Scripts/WebXRController.cs

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,26 +176,28 @@ private void OnHandUpdate(WebXRHandData handData)
176176
{
177177
if (!handData.enabled)
178178
{
179-
SetVisible(false);
180179
return;
181180
}
182-
SetVisible(true);
181+
SetVisible(false);
183182

184-
transform.localRotation = Quaternion.identity; //handData.joints[0].rotation;
185-
transform.localPosition = Vector3.zero; //handData.joints[0].position;
183+
transform.localPosition = handData.joints[0].position;
184+
transform.localRotation = handData.joints[0].rotation;
186185

187186
for(int i=0; i<=WebXRHandData.LITTLE_PHALANX_TIP; i++)
188187
{
189188
if (handData.joints[i].enabled)
190189
{
191190
if (handJoints.ContainsKey(i))
192191
{
193-
handJoints[i].localPosition = handData.joints[i].position;
194-
handJoints[i].localRotation = handData.joints[i].rotation;
192+
handJoints[i].localPosition = GetJointLocalPosition(handData.joints[i].position, handData.joints[0].position, handData.joints[0].rotation);
193+
handJoints[i].localRotation = GetJointLocalRotation(handData.joints[i].rotation, handData.joints[0].rotation);
195194
}
196195
else
197196
{
198-
var clone = Instantiate(handJointPrefab, handData.joints[i].position, handData.joints[i].rotation, transform);
197+
var clone = Instantiate(handJointPrefab,
198+
GetJointLocalPosition(handData.joints[i].position, handData.joints[0].position, handData.joints[0].rotation),
199+
GetJointLocalRotation(handData.joints[i].rotation, handData.joints[0].rotation),
200+
transform);
199201
if (handData.joints[i].radius > 0f)
200202
{
201203
clone.localScale = new Vector3(handData.joints[i].radius, handData.joints[i].radius, handData.joints[i].radius);
@@ -211,6 +213,16 @@ private void OnHandUpdate(WebXRHandData handData)
211213
}
212214
}
213215

216+
private Vector3 GetJointLocalPosition(Vector3 position, Vector3 originPosition, Quaternion originRotation)
217+
{
218+
return Quaternion.Inverse(originRotation) * (position-originPosition);
219+
}
220+
221+
private Quaternion GetJointLocalRotation(Quaternion rotation, Quaternion originRotation)
222+
{
223+
return Quaternion.Inverse(originRotation) * rotation;
224+
}
225+
214226
private WebXRControllerHand handFromString(string handValue)
215227
{
216228
WebXRControllerHand handParsed = WebXRControllerHand.NONE;

Assets/WebXR/Scripts/WebXRControllerData.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
namespace WebXR
44
{
55
[System.Serializable]
6-
public struct WebXRControllerData
6+
public class WebXRControllerData
77
{
8+
public int frame;
89
public bool enabled;
910
public int hand;
1011
public Vector3 position;
@@ -24,6 +25,7 @@ public struct WebXRControllerData
2425
[System.Serializable]
2526
public class WebXRHandData
2627
{
28+
public int frame;
2729
public bool enabled;
2830
public int hand;
2931
public WebXRJointData[] joints = new WebXRJointData[25];

Assets/WebXR/Scripts/WebXRManager.cs

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,17 @@ private static extern void set_webxr_events(Action<int> on_start_ar,
6666
float[] sharedArray = new float[5 * 16];
6767

6868
// Shared array for controllers data
69-
float[] controllersArray = new float[2 * 19];
69+
float[] controllersArray = new float[2 * 20];
7070

7171
// Shared array for hands data
72-
float[] handsArray = new float[2 * (25 * 9 + 2)];
72+
float[] handsArray = new float[2 * (25 * 9 + 3)];
7373

7474
private WebXRHandData leftHand = new WebXRHandData();
7575
private WebXRHandData rightHand = new WebXRHandData();
7676

77+
private WebXRControllerData controller1 = new WebXRControllerData();
78+
private WebXRControllerData controller2 = new WebXRControllerData();
79+
7780
private WebXRDisplayCapabilities capabilities = new WebXRDisplayCapabilities();
7881

7982
public static WebXRManager Instance
@@ -177,12 +180,21 @@ float[] GetMatrixFromSharedArray(int index)
177180
return newArray;
178181
}
179182

180-
WebXRControllerData GetGamepadFromControllersArray(int controllerIndex)
183+
bool GetGamepadFromControllersArray(int controllerIndex, ref WebXRControllerData newControllerData)
181184
{
182-
WebXRControllerData newControllerData = new WebXRControllerData();
183-
int arrayPosition = controllerIndex * 19;
185+
int arrayPosition = controllerIndex * 20;
186+
int frameNumber = (int)controllersArray[arrayPosition++];
187+
if (newControllerData.frame == frameNumber)
188+
{
189+
return false;
190+
}
191+
newControllerData.frame = frameNumber;
184192
newControllerData.enabled = controllersArray[arrayPosition++] != 0;
185193
newControllerData.hand = (int)controllersArray[arrayPosition++];
194+
if (!newControllerData.enabled)
195+
{
196+
return true;
197+
}
186198
newControllerData.position = new Vector3(controllersArray[arrayPosition++], controllersArray[arrayPosition++], controllersArray[arrayPosition++]);
187199
newControllerData.rotation = new Quaternion(controllersArray[arrayPosition++], controllersArray[arrayPosition++], controllersArray[arrayPosition++], controllersArray[arrayPosition++]);
188200
newControllerData.trigger = controllersArray[arrayPosition++];
@@ -195,17 +207,23 @@ WebXRControllerData GetGamepadFromControllersArray(int controllerIndex)
195207
newControllerData.touchpadY = controllersArray[arrayPosition++];
196208
newControllerData.buttonA = controllersArray[arrayPosition++];
197209
newControllerData.buttonB = controllersArray[arrayPosition];
198-
return newControllerData;
210+
return true;
199211
}
200212

201-
WebXRHandData GetHandFromHandsArray(int handIndex, WebXRHandData handObject)
213+
bool GetHandFromHandsArray(int handIndex, ref WebXRHandData handObject)
202214
{
203-
int arrayPosition = handIndex * 227;
215+
int arrayPosition = handIndex * 228;
216+
int frameNumber = (int)handsArray[arrayPosition++];
217+
if (handObject.frame == frameNumber)
218+
{
219+
return false;
220+
}
221+
handObject.frame = frameNumber;
204222
handObject.enabled = handsArray[arrayPosition++] != 0;
205223
handObject.hand = (int)handsArray[arrayPosition++];
206224
if (!handObject.enabled)
207225
{
208-
return handObject;
226+
return true;
209227
}
210228
for (int i=0; i<=WebXRHandData.LITTLE_PHALANX_TIP; i++)
211229
{
@@ -214,7 +232,7 @@ WebXRHandData GetHandFromHandsArray(int handIndex, WebXRHandData handObject)
214232
handObject.joints[i].rotation = new Quaternion(handsArray[arrayPosition++], handsArray[arrayPosition++], handsArray[arrayPosition++], handsArray[arrayPosition++]);
215233
handObject.joints[i].radius = handsArray[arrayPosition++];
216234
}
217-
return handObject;
235+
return true;
218236
}
219237

220238
void Start()
@@ -230,21 +248,30 @@ void Start()
230248

231249
void Update()
232250
{
233-
/*if (OnControllerUpdate != null && this.xrState != WebXRState.NORMAL)
234-
{
235-
var controller1 = GetGamepadFromControllersArray(0);
236-
OnControllerUpdate(controller1);
237-
var controller2 = GetGamepadFromControllersArray(1);
238-
OnControllerUpdate(controller2);
239-
}*/
240-
251+
bool hasHandsData = false;
241252
if (OnHandUpdate != null && this.xrState != WebXRState.NORMAL)
242253
{
243-
var hand1 = GetHandFromHandsArray(0, leftHand);
244-
OnHandUpdate(hand1);
245-
var hand2 = GetHandFromHandsArray(1, rightHand);
246-
OnHandUpdate(hand2);
247-
//Debug.LogError($"OnHandsSent {hand1.enabled} {hand2.enabled}");
254+
if (GetHandFromHandsArray(0, ref leftHand))
255+
{
256+
OnHandUpdate(leftHand);
257+
}
258+
if (GetHandFromHandsArray(1, ref rightHand))
259+
{
260+
OnHandUpdate(rightHand);
261+
}
262+
hasHandsData = leftHand.enabled || rightHand.enabled;
263+
}
264+
265+
if (!hasHandsData && OnControllerUpdate != null && this.xrState != WebXRState.NORMAL)
266+
{
267+
if (GetGamepadFromControllersArray(0, ref controller1))
268+
{
269+
OnControllerUpdate(controller1);
270+
}
271+
if (GetGamepadFromControllersArray(1, ref controller2))
272+
{
273+
OnControllerUpdate(controller2);
274+
}
248275
}
249276
}
250277

Build/Build/Build.data.unityweb

1.21 KB
Binary file not shown.

Build/Build/Build.wasm

-870 Bytes
Binary file not shown.

Build/Build/Build.wasm.framework.unityweb

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)