/// <summary> /// Updates peers on the position, scale, and rotation of this transmission object. /// </summary> public void Synchronize() { if (_isMine) { //update relative: localPosition = TransformUtilities.LocalPosition(Transmission.Instance.sharedOrigin.position, Transmission.Instance.sharedOrigin.rotation, transform.position); rotationOffset = TransformUtilities.GetRotationOffset(Transmission.Instance.sharedOrigin.rotation, transform.rotation); //send out the change to this transform: Transmission.Send(new TransformSyncMessage(this)); } }
//Init: private void Awake() { //sets: localPosition = TransformUtilities.LocalPosition(Transmission.Instance.sharedOrigin.position, Transmission.Instance.sharedOrigin.rotation, transform.position); rotationOffset = TransformUtilities.GetRotationOffset(Transmission.Instance.sharedOrigin.rotation, transform.rotation); targetScale = transform.localScale; //catalog: _all.Add(guid, this); //hooks: Transmission.Instance.OnPeerFound.AddListener(HandlePeerFound); Transmission.Instance.OnTransformSync.AddListener(HandleTransformSync); Transmission.Instance.OnOwnershipGained.AddListener(HandleOwnershipGained); Transmission.Instance.OnOwnershipTransferDenied.AddListener(HandleOwnershipTransferDenied); StartCoroutine("ShareTransformStatus"); }
private void FindWalls_LocateBoundry() { //remove initial guides: RemovePlottedBounds(); //sort by angles from a base vector to find clockwise order: Vector3 baseVector = Vector3.Normalize(_virtualWalls[0].plane.Center - _plottedBounds.center); SortedDictionary <float, int> sortedDirection = new SortedDictionary <float, int>(); for (int i = 0; i < _virtualWalls.Count; i++) { Vector3 toNext = Vector3.Normalize(_virtualWalls[i].plane.Center - _plottedBounds.center); float angle = Vector3.SignedAngle(baseVector, toNext, Vector3.up) + 180; if (sortedDirection.ContainsKey(angle)) { //we have a bad set of locations so it is best to just everything: Create(); break; } else { sortedDirection.Add(angle, i); } } int[] clockwiseOrder = sortedDirection.Values.ToArray <int>(); //find and connect 'betweens' which end up being final walls of playspace List <bool> physicalStatus = new List <bool>(); _playspaceCorners = new List <Vector3>(); for (int i = 0; i < clockwiseOrder.Length; i++) { //parts: int next = (i + 1) % clockwiseOrder.Length; float angle = Vector3.Angle(_virtualWalls[clockwiseOrder[i]].plane.Rotation * Vector3.right, _virtualWalls[clockwiseOrder[next]].plane.Rotation * Vector3.right); //save physical status: physicalStatus.Add(_virtualWalls[clockwiseOrder[next]].physical); //add solved between: if (angle < 45 || angle > 135) { //wall - use mid point: Vector3 mid = Vector3.Lerp(_virtualWalls[clockwiseOrder[i]].plane.Center, _virtualWalls[clockwiseOrder[next]].plane.Center, .5f); mid.y = _roomFloorHeight; _playspaceCorners.Add(TransformUtilities.LocalPosition(pcfAnchor.Position, pcfAnchor.Rotation, mid)); } else { //corner - use intersection by creating inverted lines from each plane: Vector3 point = Vector2.zero; if (MathUtilities.RayIntersection( new Ray(_virtualWalls[clockwiseOrder[i]].plane.Center, _virtualWalls[clockwiseOrder[i]].plane.Rotation * Vector3.right), new Ray(_virtualWalls[clockwiseOrder[next]].plane.Center, _virtualWalls[clockwiseOrder[next]].plane.Rotation * Vector3.left), ref point)) { point.y = _roomFloorHeight; _playspaceCorners.Add(TransformUtilities.LocalPosition(pcfAnchor.Position, pcfAnchor.Rotation, point)); } } } //close loop: _playspaceCorners.Add(_playspaceCorners[0]); //store walls: List <PlayspaceWall> playspaceWalls = new List <PlayspaceWall>(); for (int i = 0; i < _playspaceCorners.Count - 1; i++) { Vector3 pointA = TransformUtilities.WorldPosition(pcfAnchor.Position, pcfAnchor.Rotation, _playspaceCorners[i]); Vector3 pointB = TransformUtilities.WorldPosition(pcfAnchor.Position, pcfAnchor.Rotation, _playspaceCorners[i + 1]); Vector3 vector = pointB - pointA; Vector3 normal = Quaternion.AngleAxis(90, Vector3.up) * vector.normalized; Vector3 center = Vector3.Lerp(pointA, pointB, .5f); center.y = _roomVerticalCenter; float width = vector.magnitude; PlayspaceWall wall = new PlayspaceWall(center, Quaternion.LookRotation(normal), width, Height, physicalStatus[i]); playspaceWalls.Add(wall); } Walls = playspaceWalls.ToArray(); FindWalls_GenerateGeometry(); }
private void ConfirmPrimaryWall_HandleTriggerDown(byte controllerId, float triggerValue) { //we must have a primary wall: if (PrimaryWall == -1) { return; } //reset walls: RightWall = -1; LeftWall = -1; RearWall = -1; //find room center (this may need additional calculation for more accuracy): Bounds finalBounds = new Bounds(Walls[0].Center, Vector3.zero); for (int i = 1; i < Walls.Length; i++) { finalBounds.Encapsulate(Walls[i].Center); } //make center relative to pcf so relocalization keeps this value accurate: _playspaceCenter = TransformUtilities.LocalPosition(pcfAnchor.Position, pcfAnchor.Rotation, finalBounds.center); //find additional largest key walls: SortedDictionary <float, int> rightWalls = new SortedDictionary <float, int>(); SortedDictionary <float, int> rearWalls = new SortedDictionary <float, int>(); SortedDictionary <float, int> leftWalls = new SortedDictionary <float, int>(); for (int i = 0; i < Walls.Length; i++) { //skip walls that match the primary: if (i != PrimaryWall) //skip primary wall and walls on the same plane { //get angle relationship: float angle = Vector3.SignedAngle(Walls[PrimaryWall].Normal, Walls[i].Normal, Vector3.up); if (angle < 0) { angle += 360; } //get size: float wallSize = Walls[i].width * Walls[i].height; //right: if (angle >= 225 && angle < 315) { leftWalls.Add(wallSize, i); } //rear: if (angle > 135 && angle < 225) { rearWalls.Add(wallSize, i); } //left: if (angle >= 45 && angle <= 135) { rightWalls.Add(wallSize, i); } } } //set key walls to largest (might need to verify they are also facing the correct direction as well later): if (rightWalls.Count != 0) { RightWall = rightWalls.ElementAt(rightWalls.Count - 1).Value; } if (rearWalls.Count != 0) { RearWall = rearWalls.ElementAt(rearWalls.Count - 1).Value; } if (leftWalls.Count != 0) { LeftWall = leftWalls.ElementAt(leftWalls.Count - 1).Value; } //unhook: MLInput.OnTriggerDown -= ConfirmPrimaryWall_HandleTriggerDown; //something went wrong with the shape of the room, best to force a rest: if (PrimaryWall == -1 || LeftWall == -1 || RightWall == -1 || RearWall == -1) { Create(); } else { ChangeState(State.Complete); } }