void RecordPose(float delta, Pose p) { if (packet == null) //If this is our first packet, store the pose as the initial frame { packet = new OvrAvatarPacket(p); delta = 0; } var recorded = 0f; while (recorded < delta) { var left = delta - recorded; var inPacket = PacketDurationSec - packet.LastTime; //what if it's negative? if (left < inPacket) //If we're not going to fill the packet, just add the frame { packet.AddFrame(p, left); recorded += left; } else { // If we're going to fill the packet, interpolate the pose, send the packet, // and open a new one // Interpolate between the packet's last frame and our target pose // to compute a pose at the end of the packet time. var pose = Pose.Interpolate(packet.LastFrame, p, inPacket / left); packet.AddFrame(pose, inPacket); recorded += inPacket; PacketRecorded?.Invoke(this, new PacketEventArgs(packet)); //Broadcast the recorded packet packet = new OvrAvatarPacket(pose); //Open a new packet } } }
public void processAvatarPacket(RemotePlayer remote, ref byte[] packet, ref int offset) { if (remote == null) { return; } remote.receivedRootPositionPrior = remote.receivedRootPosition; remote.receivedRootPosition.x = ReadFloat(packet, ref offset); remote.receivedRootPosition.y = ReadFloat(packet, ref offset); remote.receivedRootPosition.z = ReadFloat(packet, ref offset); remote.receivedRootRotationPrior = remote.receivedRootRotation; remote.receivedRootRotation.x = ReadFloat(packet, ref offset); remote.receivedRootRotation.y = ReadFloat(packet, ref offset); remote.receivedRootRotation.z = ReadFloat(packet, ref offset); remote.receivedRootRotation.w = ReadFloat(packet, ref offset); remote.RemoteAvatar.transform.position = remote.receivedRootPosition; remote.RemoteAvatar.transform.rotation = remote.receivedRootRotation; // forward the remaining data to the avatar system int sequence = (int)ReadUInt32(packet, ref offset); byte[] remainingAvatarBuffer = new byte[packet.Length - offset]; Buffer.BlockCopy(packet, offset, remainingAvatarBuffer, 0, remainingAvatarBuffer.Length); IntPtr avatarPacket = Oculus.Avatar.CAPI.ovrAvatarPacket_Read((UInt32)remainingAvatarBuffer.Length, remainingAvatarBuffer); var ovravatarPacket = new OvrAvatarPacket { ovrNativePacket = avatarPacket }; remote.RemoteAvatar.GetComponent <OvrAvatarRemoteDriver>().QueuePacket(sequence, ovravatarPacket); }
void ReceivePacketData(byte[] data) { using (MemoryStream inputStream = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(inputStream); int sequence = reader.ReadInt32(); OvrAvatarPacket avatarPacket; if (LoopbackAvatar.UseSDKPackets) { int size = reader.ReadInt32(); byte[] sdkData = reader.ReadBytes(size); IntPtr packet = CAPI.ovrAvatarPacket_Read((UInt32)data.Length, sdkData); avatarPacket = new OvrAvatarPacket { ovrNativePacket = packet }; } else { avatarPacket = OvrAvatarPacket.Read(inputStream); } LoopbackAvatar.GetComponent <OvrAvatarRemoteDriver>().QueuePacket(sequence, avatarPacket); } }
void Update() { if (!isStreaming && packetQueue.Count > MinPacketQueue) //If we're not currently streaming, check to see if we've buffered enough { currentPacket = packetQueue.Dequeue(); isStreaming = true; } if (isStreaming) //If we are streaming, update our pose { currentPacketTime += Time.deltaTime; while (currentPacketTime > currentPacket.LastTime) //If we've elapsed past our current packet, advance { if (packetQueue.Count == 0) //If we're out of packets, stop streaming and lock to the final frame { currentPose = currentPacket.LastFrame; currentPacketTime = 0.0f; currentPacket = null; isStreaming = false; return; } while (packetQueue.Count > MaxPacketQueue) { packetQueue.Dequeue(); } currentPacketTime -= currentPacket.LastTime; //Otherwise, dequeue the next packet currentPacket = packetQueue.Dequeue(); } currentPose = currentPacket.GetPoseFrame(currentPacketTime); //Compute the pose based on our current time offset in the packet } }
public void QueuePacket(int sequence, OvrAvatarPacket packet) { if (sequence > CurrentSequence) { CurrentSequence = sequence; packetQueue.Enqueue(packet); } }
public void QueuePacket(int sequence, OvrAvatarPacket packet) { if (sequence - currentSequence < 0) { return; } currentSequence = sequence; packetQueue.Enqueue(packet); }
void ReceivePacketData(byte[] data) { using (MemoryStream inputStream = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(inputStream); int sequence = reader.ReadInt32(); OvrAvatarPacket packet = OvrAvatarPacket.Read(inputStream); LoopbackAvatar.GetComponent <OvrAvatarRemoteDriver>().QueuePacket(sequence, packet); } }
// Meant to be used mutually exclusively with RecordSDKFrame to give user more options to optimize or tweak packet data private void RecordUnityFrame() { var deltaSeconds = Time.deltaTime; var frame = Driver.GetCurrentPose(); // If this is our first packet, store the pose as the initial frame if (CurrentUnityPacket == null) { CurrentUnityPacket = new OvrAvatarPacket(frame); deltaSeconds = 0; } float recordedSeconds = 0; while (recordedSeconds < deltaSeconds) { float remainingSeconds = deltaSeconds - recordedSeconds; float remainingPacketSeconds = PacketSettings.UpdateRate - CurrentUnityPacket.Duration; // If we're not going to fill the packet, just add the frame if (remainingSeconds < remainingPacketSeconds) { CurrentUnityPacket.AddFrame(frame, remainingSeconds); recordedSeconds += remainingSeconds; } // If we're going to fill the packet, interpolate the pose, send the packet, // and open a new one else { // Interpolate between the packet's last frame and our target pose // to compute a pose at the end of the packet time. OvrAvatarDriver.PoseFrame a = CurrentUnityPacket.FinalFrame; OvrAvatarDriver.PoseFrame b = frame; float t = remainingPacketSeconds / remainingSeconds; OvrAvatarDriver.PoseFrame intermediatePose = OvrAvatarDriver.PoseFrame.Interpolate(a, b, t); CurrentUnityPacket.AddFrame(intermediatePose, remainingPacketSeconds); recordedSeconds += remainingPacketSeconds; // Broadcast the recorded packet if (PacketRecorded != null) { PacketRecorded(this, new PacketEventArgs(CurrentUnityPacket)); } // Open a new packet CurrentUnityPacket = new OvrAvatarPacket(intermediatePose); } } }
private void UpdateFromUnityPacket(IntPtr sdkAvatar) { // If we're not currently streaming, check to see if we've buffered enough if (!isStreaming && packetQueue.Count > MinPacketQueue) { currentPacket = packetQueue.Dequeue(): isStreaming = true: } // If we are streaming, update our pose if (isStreaming) { CurrentPacketTime += Time.deltaTime: // If we've elapsed past our current packet, advance while (CurrentPacketTime > currentPacket.Duration) { // If we're out of packets, stop streaming and // lock to the final frame if (packetQueue.Count == 0) { CurrentPose = currentPacket.FinalFrame: CurrentPacketTime = 0.0f: currentPacket = null: isStreaming = false: return: } while (packetQueue.Count > MaxPacketQueue) { packetQueue.Dequeue(): } // Otherwise, dequeue the next packet CurrentPacketTime -= currentPacket.Duration: currentPacket = packetQueue.Dequeue(): } // Compute the pose based on our current time offset in the packet CurrentPose = currentPacket.GetPoseFrame(CurrentPacketTime): UpdateTransformsFromPose(sdkAvatar): } }
void ReceivePacketData(byte[] data) { using (MemoryStream inputStream = new MemoryStream(data)) { BinaryReader reader = new BinaryReader(inputStream); int sequence = reader.ReadInt32(); OvrAvatarPacket packet = OvrAvatarPacket.Read(inputStream); LoopbackAvatar.GetComponent <OvrAvatarRemoteDriver>().QueuePacket(sequence, packet); // BinaryReader reader = new BinaryReader(inputStream); // int sequence = reader.ReadInt32(); // int size = reader.ReadInt32(); // byte[] sdkData = reader.ReadBytes(size); // IntPtr packet = CAPI.ovrAvatarPacket_Read((UInt32)data.Length, sdkData); // LoopbackAvatar.GetComponent<OvrAvatarRemoteDriver>().QueuePacket(sequence, new OvrAvatarPacket { ovrNativePacket = packet }); } }
public PacketEventArgs(OvrAvatarPacket packet) { Packet = packet; }
// Update is called once per frame void Update() { // Ping everyone every 5 seconds float now = Time.time; if ((Time.time - lastPingTime) > 5) { foreach (var connection in remoteConnectionStates) { if (connection.Value.networkState == ConnectionState.Connected) { Net.Ping(connection.Key); } } lastPingTime = now; } if (OVRInput.GetDown(OVRInput.RawButton.B) || Input.GetKeyDown(KeyCode.Space)) { var caemraRig = GameObject.Find("OVRCameraRig"); caemraRig.transform.RotateAround(new Vector3(0, 0, 0), new Vector3(0, 1, 0), 90); } if (ReadyToPlay()) { if (OVRInput.Get(OVRInput.Axis1D.SecondaryIndexTrigger) > 0.55) { if ((rightHandHeld == null) && (rightHandGrabber.otherCollider != null)) { if (rightHandGrabber.otherCollider == deckCollider) { rightHandHeld = deckController.getNextCard( deckController.transform.position, deckController.transform.rotation); } else { rightHandHeld = rightHandGrabber.otherCollider.gameObject; } // Might not be in the hand, but it's as costly to check and no harm in trying if (cardHandController.isCardInHand(rightHandHeld)) { cardHandController.ReleaseCard(rightHandHeld); } rightHandHeld.transform.parent = rightHandAnchor.transform; rightHandHeld.GetComponent <Rigidbody>().isKinematic = true; rightHandHeld.GetComponent <SimpleGrabbable>().isGrabbed = true; } } if (OVRInput.Get(OVRInput.Axis1D.SecondaryIndexTrigger) < 0.35) { if (rightHandHeld != null) { rightHandHeld.transform.parent = null; rightHandHeld.GetComponent <Rigidbody>().isKinematic = false; rightHandHeld.GetComponent <SimpleGrabbable>().isGrabbed = false; if ((rightHandHeld.GetComponent <CardController>() != null) && cardHandController.isHighlighting) { cardHandController.AddCard(rightHandHeld); } else { // Notify remote users that we are dropping the card OnRigidBodyUpdate(rightHandHeld.GetComponent <Rigidbody>()); } rightHandHeld = null; } } } Packet packet; while ((packet = Net.ReadPacket()) != null) { byte[] packetBuf = new byte[packet.Size]; packet.ReadBytes(packetBuf); packet.Dispose(); using (BinaryReader binaryReader = new BinaryReader(new MemoryStream(packetBuf))) { var type = (PacketType)binaryReader.ReadByte(); var userID = binaryReader.ReadUInt64(); switch (type) { case PacketType.AVATAR_UPDATE: var position = binaryReader.ReadVector3(); var orientation = binaryReader.ReadQuaternion(); var avatarPacketSequence = binaryReader.ReadInt32(); var avatar = remoteAvatars.ContainsKey(userID) ? remoteAvatars[userID] : null; if (avatar != null) { OvrAvatarPacket avatarPacket = null; int size = binaryReader.ReadInt32(); byte[] sdkData = binaryReader.ReadBytes(size); IntPtr tempPacket = Oculus.Avatar.CAPI.ovrAvatarPacket_Read((UInt32)sdkData.Length, sdkData); avatarPacket = new OvrAvatarPacket { ovrNativePacket = tempPacket }; avatar.transform.position = position; avatar.transform.rotation = orientation; avatar.GetComponent <OvrAvatarRemoteDriver>().QueuePacket(avatarPacketSequence, avatarPacket); } break; case PacketType.TRACKED_OBJECT_UPDATE: var objName = binaryReader.ReadString(); var objPosition = binaryReader.ReadVector3(); var objOrientation = binaryReader.ReadQuaternion(); var obj = getTrackedObject(objName); if (obj != null) { obj.transform.parent = null; var rigidBody = obj.GetComponent <Rigidbody>(); if (rigidBody) { rigidBody.isKinematic = true; } obj.transform.position = objPosition; obj.transform.rotation = objOrientation; } break; case PacketType.DECK_UPDATE: var cardCount = binaryReader.ReadByte(); var cardIndex = binaryReader.ReadByte(); var cards = binaryReader.ReadBytes(cardCount); UnityUserReporting.CurrentClient.LogEvent(UserReportEventLevel.Info, "Received - deck update from " + userID.ToString() + " - " + cardIndex); deckController.updateDeck(new List <byte>(cards), cardIndex); break; case PacketType.CARD_HAND_UPDATE: var cardHandCount = binaryReader.ReadByte(); var cardHand = binaryReader.ReadBytes(cardHandCount); if (remoteCardHands.ContainsKey(userID)) { remoteCardHands[userID].updateCardHand(cardHand); } else if (userID != localUser.ID) // Can happen on state updates { if (pendingCardHandUpdates.ContainsKey(userID)) { pendingCardHandUpdates[userID] = cardHand; } else { pendingCardHandUpdates.Add(userID, cardHand); } } break; case PacketType.RIGID_BODY_UPDATE: var rigidObjName = binaryReader.ReadString(); var rigidBodyPostion = binaryReader.ReadVector3(); var rigidBodyRotation = binaryReader.ReadQuaternion(); // TO DO - This isn't really an exciting implementation var rigidObj = getTrackedObject(rigidObjName); if (rigidObj != null) { rigidObj.transform.position = rigidBodyPostion; rigidObj.transform.rotation = rigidBodyRotation; rigidObj.GetComponent <Rigidbody>().isKinematic = false; } break; case PacketType.RESET: UnityUserReporting.CurrentClient.LogEvent(UserReportEventLevel.Info, "Received - reset from " + userID.ToString()); resetGame(); break; case PacketType.STATE_UPDATE_REQUEST: UnityUserReporting.CurrentClient.LogEvent(UserReportEventLevel.Info, "Received - state update request from " + userID.ToString()); deckController.SendUpdate(); cardHandController.SendUpdate(); foreach (var remoteCardHand in remoteCardHands.Values) { remoteCardHand.SendUpdate(); } // Cards without a parent won't be captured otherwise var allCards = GameObject.FindGameObjectsWithTag("PlayingCard"); foreach (var card in allCards) { if (card.transform.parent == null) { OnRigidBodyUpdate(card.GetComponent <Rigidbody>()); } } break; default: UnityUserReporting.CurrentClient.LogEvent(UserReportEventLevel.Error, "Unexpected packete received " + type.ToString()); Debug.LogError("Unexpected case"); break; } } } var mouthsAttached = new List <ulong>(); foreach (var id in pendingMouthAnchorAttach) { if (remoteAvatars.ContainsKey(id) && remoteAvatars[id].MouthAnchor != null) { if (remoteAvatars[id].MouthAnchor.GetComponent <VoipAudioSourceHiLevel>() != null) { UnityUserReporting.CurrentClient.LogEvent(UserReportEventLevel.Warning, "Attempted to add second voip audio source for " + id.ToString()); } else { var source = remoteAvatars[id].MouthAnchor.AddComponent <VoipAudioSourceHiLevel>(); source.senderID = id; UnityUserReporting.CurrentClient.LogEvent(UserReportEventLevel.Info, "Adding voip audio source for " + id.ToString()); } mouthsAttached.Add(id); } } foreach (var id in mouthsAttached) { pendingMouthAnchorAttach.Remove(id); } var handsAttached = new List <ulong>(); foreach (var id in pendingLeftCardHandAttach) { if (remoteAvatars.ContainsKey(id) && remoteAvatars[id].HandLeft != null) { if (remoteAvatars[id].HandLeft.gameObject.GetComponent <CardHandController>() != null) { UnityUserReporting.CurrentClient.LogEvent(UserReportEventLevel.Warning, "Attempted to add second card hand for " + id.ToString()); } else { var newCardHand = remoteAvatars[id].HandLeft.gameObject.AddComponent <CardHandController>(); newCardHand.canastyController = this; remoteCardHands.Add(id, newCardHand); UnityUserReporting.CurrentClient.LogEvent(UserReportEventLevel.Info, "Adding remote hand object for " + id.ToString()); } if (pendingCardHandUpdates.ContainsKey(id)) { UnityUserReporting.CurrentClient.LogEvent(UserReportEventLevel.Info, "Updating pending card hand for " + id.ToString()); remoteCardHands[id].updateCardHand(pendingCardHandUpdates[id]); } handsAttached.Add(id); } } foreach (var id in handsAttached) { pendingLeftCardHandAttach.Remove(id); pendingCardHandUpdates.Remove(id); } // Update unity user reporting reportingUpdater.Reset(); this.StartCoroutine(this.reportingUpdater); }
public void QueuePacket(int sequence, OvrAvatarPacket packet) { packetQueue.Enqueue(packet); }