//---------------------------------------------------------------------------------------
  // # Skookum:   Vector3@unrotate_by(Rotation rot) Vector3
  // # Author(s): Markus Breyer
  static void mthd_unrotate_by(SkInvokedMethod * scope_p, SkInstance ** result_pp)
    {
    // Do nothing if result not desired
    if (result_pp)
      {
      const FVector & vec = scope_p->this_as<SkVector3>();
      const FQuat rot = scope_p->get_arg<SkRotation>(SkArg_1);

      *result_pp = SkVector3::new_instance(rot.Inverse().RotateVector(vec));
      }
    }
  //---------------------------------------------------------------------------------------
  // # Skookum:   Vector3@unrotate_by(Rotation rot) Vector3
  // # Author(s): Markus Breyer
  static void mthd_unrotate_by(SSInvokedMethod * scope_p, SSInstance ** result_pp)
    {
    // Do nothing if result not desired
    if (result_pp)
      {
      const FVector & vec = *scope_p->this_as<FVector>();
      const FQuat rot = *scope_p->get_arg<FQuat>(SSArg_1);

      *result_pp = as_instance(rot.Inverse().RotateVector(vec));
      }
    }
Ejemplo n.º 3
0
FVector FGearVR::GetNeckPosition(const FQuat& CurrentOrientation, const FVector& CurrentPosition, const FVector& PositionScale)
{
	const auto frame = GetFrame();
	if (!frame)
	{
		return FVector::ZeroVector;
	}
	FVector UnrotatedPos = CurrentOrientation.Inverse().RotateVector(CurrentPosition);
	UnrotatedPos.X -= frame->Settings->NeckToEyeInMeters.X * frame->WorldToMetersScale;
	UnrotatedPos.Z -= frame->Settings->NeckToEyeInMeters.Y * frame->WorldToMetersScale;
	return UnrotatedPos;
}
Ejemplo n.º 4
0
FRotator UKismetMathLibrary::NegateRotator( FRotator A )
{
	FQuat AQuat = FQuat(A);
	return FRotator(AQuat.Inverse());
}
Ejemplo n.º 5
0
void FViewExtension::PreRenderView_RenderThread(FRHICommandListImmediate& RHICmdList, FSceneView& View)
{
	check(IsInRenderingThread());
	FViewExtension& RenderContext = *this;
	FGameFrame* CurrentFrame = static_cast<FGameFrame*>(RenderContext.RenderFrame.Get());

	if (!RenderContext.ShowFlags.Rendering || !CurrentFrame || !CurrentFrame->Settings->IsStereoEnabled())
	{
		return;
	}

	const ovrEyeType eyeIdx = (View.StereoPass == eSSP_LEFT_EYE) ? ovrEye_Left : ovrEye_Right;
	if (RenderContext.ShowFlags.Rendering && CurrentFrame->Settings->Flags.bUpdateOnRT)
	{
		FQuat	CurrentEyeOrientation;
		FVector	CurrentEyePosition;
		CurrentFrame->PoseToOrientationAndPosition(RenderContext.CurEyeRenderPose[eyeIdx], CurrentEyeOrientation, CurrentEyePosition);

		FQuat ViewOrientation = View.ViewRotation.Quaternion();

		// recalculate delta control orientation; it should match the one we used in CalculateStereoViewOffset on a game thread.
		FVector GameEyePosition;
		FQuat GameEyeOrient;

		CurrentFrame->PoseToOrientationAndPosition(CurrentFrame->EyeRenderPose[eyeIdx], GameEyeOrient, GameEyePosition);
		const FQuat DeltaControlOrientation =  ViewOrientation * GameEyeOrient.Inverse();
		// make sure we use the same viewrotation as we had on a game thread
		check(View.ViewRotation == CurrentFrame->CachedViewRotation[eyeIdx]);

		if (CurrentFrame->Flags.bOrientationChanged)
		{
			// Apply updated orientation to corresponding View at recalc matrices.
			// The updated position will be applied from inside of the UpdateViewMatrix() call.
			const FQuat DeltaOrient = View.BaseHmdOrientation.Inverse() * CurrentEyeOrientation;
			View.ViewRotation = FRotator(ViewOrientation * DeltaOrient);
			
			//UE_LOG(LogHMD, Log, TEXT("VIEWDLT: Yaw %.3f Pitch %.3f Roll %.3f"), DeltaOrient.Rotator().Yaw, DeltaOrient.Rotator().Pitch, DeltaOrient.Rotator().Roll);
		}

		if (!CurrentFrame->Flags.bPositionChanged)
		{
			// if no positional change applied then we still need to calculate proper stereo disparity.
			// use the current head pose for this calculation instead of the one that was saved on a game thread.
			FQuat HeadOrientation;
			CurrentFrame->PoseToOrientationAndPosition(RenderContext.CurHeadPose, HeadOrientation, View.BaseHmdLocation);
		}

		// The HMDPosition already has HMD orientation applied.
		// Apply rotational difference between HMD orientation and ViewRotation
		// to HMDPosition vector. 
		const FVector DeltaPosition = CurrentEyePosition - View.BaseHmdLocation;
		const FVector vEyePosition = DeltaControlOrientation.RotateVector(DeltaPosition) + CurrentFrame->Settings->PositionOffset;
		View.ViewLocation += vEyePosition;

		//UE_LOG(LogHMD, Log, TEXT("VDLTPOS: %.3f %.3f %.3f"), vEyePosition.X, vEyePosition.Y, vEyePosition.Z);

		if (CurrentFrame->Flags.bOrientationChanged || CurrentFrame->Flags.bPositionChanged)
		{
			View.UpdateViewMatrix();
		}
	}

	FSettings* FrameSettings = CurrentFrame->GetSettings();
	check(FrameSettings);
	FrameSettings->EyeLayer.EyeFov.RenderPose[eyeIdx] = RenderContext.CurEyeRenderPose[eyeIdx];
}
Ejemplo n.º 6
0
void vtIcoGlobe::CreateUnfoldableDymax()
{
    int i;
    for (i = 0; i < 22; i++)
    {
        m_mface[i].xform = new vtTransform;
        m_mface[i].surfgroup = new vtGroup;
        m_mface[i].surfgroup->SetEnabled(false);
        m_mface[i].geode = new vtGeode;
        m_mface[i].xform->addChild(m_mface[i].geode);
        m_mface[i].xform->addChild(m_mface[i].surfgroup);

        vtString str;
        str.Format("IcoFace %d", i);
        m_mface[i].xform->setName(str);

        int face = dymax_subfaces[i].face;
        int subfaces = dymax_subfaces[i].subfaces;

        bool which;
        int mat = GetMaterialForFace(face, which);

        add_face2(m_mesh[i], face, i, subfaces, which);

        m_mface[i].geode->SetMaterials(m_earthmats);
        m_mface[i].geode->AddMesh(m_mesh[i], m_globe_mat[mat]);
    }
    m_top->addChild(m_mface[0].xform);

    m_mface[0].local_origin.Set(0,0,0);
    for (i = 1; i < 22; i++)
        FindLocalOrigin(i);
    for (i = 1; i < 22; i++)
        SetMeshConnect(i);

    // Determine necessary rotation to orient flat map toward viewer.
    FQuat qface;
    DPoint3 v0 = m_verts[icosa_face_v[0][0]];
    DPoint3 v1 = m_verts[icosa_face_v[0][1]];
    DPoint3 v2 = m_verts[icosa_face_v[0][2]];

    // Create a rotation to turn the globe so that a specific edge
    //  is pointed down -X for proper map orientation
    DPoint3 edge = v2 - v0;
    edge.Normalize();

    // compose face norm and face quaternion
    DPoint3 fnorm = (v0 + v1 + v2).Normalize();
    qface.SetFromVectors(edge, fnorm);

    // desired vector points down -X
    FQuat qdesired;
    qdesired.SetFromVectors(FPoint3(-1,0,0),FPoint3(0,0,1));

    // determine rotational difference
    m_diff = qface.Inverse() * qdesired;

#if 0
    // scaffolding mesh for debugging
    vtMesh *sm = new vtMesh(GL_LINES, VT_Colors, 12);
    sm->AddVertex(v0*1.0001f);
    sm->AddVertex(v1*1.0001f);
    sm->AddVertex(v2*1.0001f);
    sm->AddVertex(v0*1.0001f+fnorm);
    sm->SetVtxColor(0, RGBf(1,0,0));
    sm->SetVtxColor(1, RGBf(0,1,0));
    sm->SetVtxColor(2, RGBf(0,0,1));
    sm->SetVtxColor(3, RGBf(1,1,0));
    sm->AddLine(0,1);
    sm->AddLine(0,2);
    sm->AddLine(0,3);
    m_geom[0]->AddMesh(sm, m_red);
    sm->Release();
#endif

    // Show axis of rotation (north and south poles)
    vtMaterialArray *pMats = new vtMaterialArray;
    int green = pMats->AddRGBMaterial1(RGBf(0,1,0), false, false);
    m_pAxisGeom = new vtGeode;
    m_pAxisGeom->setName("AxisGeom");
    m_pAxisGeom->SetMaterials(pMats);
    m_pAxisGeom->SetEnabled(false);

    vtMesh *pMesh = new vtMesh(osg::PrimitiveSet::LINES, 0, 6);
    pMesh->AddVertex(FPoint3(0,2,0));
    pMesh->AddVertex(FPoint3(0,-2,0));
    pMesh->AddLine(0,1);
    m_pAxisGeom->AddMesh(pMesh, green);
    m_top->addChild(m_pAxisGeom);

#if 0
    axis = WireAxis(RGBf(1,1,1), 1.1f);
    m_top->addChild(axis);
#endif
}
Ejemplo n.º 7
0
void FLeapMotionInputDevice::ParseEvents()
{
	//Optimization: If we don't have any delegates, skip
	if (EventDelegates.Num() == 0)
	{
		return;
	}

	//Pointers
	Leap::Frame Frame = ControllerData.LeapController.frame();
	Leap::Frame PastFrame = ControllerData.LeapController.frame(1);

	//Calculate HMD Timewarp if valid
	if (GEngine->HMDDevice.IsValid() && ControllerData.bTimeWarpEnabled) {
		LeapHMDSnapshot ThenSnapshot = HMDSamples->HMDSampleClosestToTimestamp(Frame.timestamp());
		LeapHMDSnapshot NowSnapShot = HMDSamples->CurrentHMDSample();

		LeapHMDSnapshot HistorySnapshot = HMDSamples->LastHMDSample();	//reduce jitter
		//ControllerData.TimeWarpSnapshot = NowSnapShot.Difference(ThenSnapshot, ControllerData.TimeWarpFactor);// * ControllerData.TimeWarpFactor;

		FQuat WarpQuat = NowSnapShot.Orientation;//FQuat::Slerp(NowSnapShot.Orientation, HistorySnapshot.Orientation, ControllerData.TimeWarpTween);
		FQuat ThenTweened = FQuat::Slerp(ThenSnapshot.Orientation, HistorySnapshot.Orientation, ControllerData.TimeWarpTween);

		ControllerData.TimeWarpSnapshot.Orientation = (WarpQuat.Inverse() * ControllerData.TimeWarpFactor) * ThenTweened;

		ControllerData.TimeWarpAmountMs = (ControllerData.TimeWarpSnapshot.Timestamp) / 1000.f;
	}

	//-Hands-

	//Hand Count
	int HandCount = Frame.hands().count();

	if (PastState->HandCount != HandCount)
	{
		CallFunctionOnDelegates([&](UObject* EventDelegate)
		{
			ILeapEventInterface::Execute_HandCountChanged(EventDelegate, HandCount);
		});
		//Zero our input mapping orientations (akin to letting go of a joystick)
		if (HandCount == 0)
		{
			EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmPitch, 0, 0, 0);
			EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmYaw, 0, 0, 0);
			EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmRoll, 0, 0, 0);
			EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmPitch, 0, 0, 0);
			EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmYaw, 0, 0, 0);
			EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmRoll, 0, 0, 0);
		}
	}

	//Cycle through each hand
	for (int i = 0; i < HandCount; i++)
	{
		Leap::Hand Hand = Frame.hands()[i];
		LeapHandStateData PastHandState = PastState->StateForId(Hand.id());		//we use a custom class to hold reliable state tracking based on id's

																				//Make a ULeapHand
		if (PEventHand == nullptr)
		{
			PEventHand = NewObject<ULeapHand>();
			PEventHand->AddToRoot();
		}
		PEventHand->SetHand(Hand);

		//Emit hand
		CallFunctionOnDelegates([&](UObject* EventDelegate)
		{
			ILeapEventInterface::Execute_LeapHandMoved(EventDelegate, PEventHand);
		});


		//Left/Right hand forwarding
		if (Hand.isRight())
		{
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_LeapRightHandMoved(EventDelegate, PEventHand);
			});

			//Input Mapping
			FRotator PalmOrientation = PEventHand->PalmOrientation;
			EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmPitch, PalmOrientation.Pitch * LEAP_IM_SCALE, 0, 0);
			EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmYaw, PalmOrientation.Yaw * LEAP_IM_SCALE, 0, 0);
			EmitAnalogInputEventForKey(EKeysLeap::LeapRightPalmRoll, PalmOrientation.Roll * LEAP_IM_SCALE, 0, 0);
		}
		else if (Hand.isLeft())
		{
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_LeapLeftHandMoved(EventDelegate, PEventHand);
			});

			//Input Mapping
			FRotator PalmOrientation = PEventHand->PalmOrientation;
			EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmPitch, PalmOrientation.Pitch * LEAP_IM_SCALE, 0, 0);
			EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmYaw, PalmOrientation.Yaw * LEAP_IM_SCALE, 0, 0);
			EmitAnalogInputEventForKey(EKeysLeap::LeapLeftPalmRoll, PalmOrientation.Roll * LEAP_IM_SCALE, 0, 0);
		}

		//Grabbing
		float GrabStrength = Hand.grabStrength();
		bool Grabbed = HandClosed(GrabStrength);

		if (Grabbed)
		{
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_LeapHandGrabbing(EventDelegate, GrabStrength, PEventHand);
			});

		}

		if (Grabbed && !PastHandState.Grabbed)
		{
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_LeapHandGrabbed(EventDelegate, GrabStrength, PEventHand);
			});

			//input mapping
			if (PEventHand->HandType == LeapHandType::HAND_LEFT)
			{
				EmitKeyDownEventForKey(EKeysLeap::LeapLeftGrab, 0, 0);
			}
			else
			{
				EmitKeyDownEventForKey(EKeysLeap::LeapRightGrab, 0, 0);
			}
		}
		else if (!Grabbed && PastHandState.Grabbed)
		{
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_LeapHandReleased(EventDelegate, GrabStrength, PEventHand);
			});

			//input mapping
			if (PEventHand->HandType == LeapHandType::HAND_LEFT)
			{
				EmitKeyUpEventForKey(EKeysLeap::LeapLeftGrab, 0, 0);
			}
			else
			{
				EmitKeyUpEventForKey(EKeysLeap::LeapRightGrab, 0, 0);
			}
		}

		//Pinching
		float PinchStrength = Hand.pinchStrength();
		bool Pinched = HandPinched(PinchStrength);

		//While grabbing disable pinching detection, this helps to reduce spam as pose confidence plummets
		if (Grabbed)
		{
			Pinched = PastHandState.Pinched;
		}
		else
		{
			if (Pinched)
			{
				CallFunctionOnDelegates([&](UObject* EventDelegate)
				{
					ILeapEventInterface::Execute_LeapHandPinching(EventDelegate, PinchStrength, PEventHand);
				});
			}
			if (Pinched && !PastHandState.Pinched)
			{
				CallFunctionOnDelegates([&](UObject* EventDelegate)
				{
					ILeapEventInterface::Execute_LeapHandPinched(EventDelegate, PinchStrength, PEventHand);
				});
				//input mapping
				if (PEventHand->HandType == LeapHandType::HAND_LEFT)
				{
					EmitKeyDownEventForKey(EKeysLeap::LeapLeftPinch, 0, 0);
				}
				else
				{
					EmitKeyDownEventForKey(EKeysLeap::LeapRightPinch, 0, 0);
				}
			}
			else if (!Pinched && PastHandState.Pinched)
			{
				CallFunctionOnDelegates([&](UObject* EventDelegate)
				{
					ILeapEventInterface::Execute_LeapHandUnpinched(EventDelegate, PinchStrength, PEventHand);
				});
				//input mapping
				if (PEventHand->HandType == LeapHandType::HAND_LEFT)
				{
					EmitKeyUpEventForKey(EKeysLeap::LeapLeftPinch, 0, 0);
				}
				else
				{
					EmitKeyUpEventForKey(EKeysLeap::LeapRightPinch, 0, 0);
				}
			}
		}

		//-Fingers-
		Leap::FingerList Fingers = Hand.fingers();

		//Count
		int FingerCount = Fingers.count();
		if ((PastHandState.FingerCount != FingerCount))
		{
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_FingerCountChanged(EventDelegate, FingerCount);
			});
		}
		if (PEventFinger == nullptr)
		{
			PEventFinger = NewObject<ULeapFinger>();
			PEventFinger->AddToRoot();
		}

		Leap::Finger Finger;

		//Cycle through each finger
		for (int j = 0; j < FingerCount; j++)
		{
			Finger = Fingers[j];
			PEventFinger->SetFinger(Finger);

			//Finger Moved
			if (Finger.isValid())
			{
				CallFunctionOnDelegates([&](UObject* EventDelegate)
				{
					ILeapEventInterface::Execute_LeapFingerMoved(EventDelegate, PEventFinger);
				});
			}
		}

		//Do these last so we can easily override debug shapes

		//Leftmost
		Finger = Fingers.leftmost();
		PEventFinger->SetFinger(Finger);
		CallFunctionOnDelegates([&](UObject* EventDelegate)
		{
			ILeapEventInterface::Execute_LeapLeftMostFingerMoved(EventDelegate, PEventFinger);
		});

		//Rightmost
		Finger = Fingers.rightmost();
		PEventFinger->SetFinger(Finger);
		CallFunctionOnDelegates([&](UObject* EventDelegate)
		{
			ILeapEventInterface::Execute_LeapRightMostFingerMoved(EventDelegate, PEventFinger);
		});

		//Frontmost
		Finger = Fingers.frontmost();
		PEventFinger->SetFinger(Finger);
		CallFunctionOnDelegates([&](UObject* EventDelegate)
		{
			ILeapEventInterface::Execute_LeapFrontMostFingerMoved(EventDelegate, PEventFinger);
		});

		//touch only for front-most finger, most common use case
		float touchDistance = Finger.touchDistance();
		if (touchDistance <= 0.f)
		{
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_LeapFrontFingerTouch(EventDelegate, PEventFinger);
			});
		}

		//Set the state data for next cycle
		PastHandState.Grabbed = Grabbed;
		PastHandState.Pinched = Pinched;
		PastHandState.FingerCount = FingerCount;

		PastState->SetStateForId(PastHandState, Hand.id());
	}

	PastState->HandCount = HandCount;

	//Gestures
	for (int i = 0; i < Frame.gestures().count(); i++)
	{
		Leap::Gesture Gesture = Frame.gestures()[i];
		Leap::Gesture::Type Type = Gesture.type();

		switch (Type)
		{
		case Leap::Gesture::TYPE_CIRCLE:
			if (PEventCircleGesture == nullptr)
			{
				PEventCircleGesture = NewObject<ULeapCircleGesture>();
				PEventCircleGesture->AddToRoot();
			}
			PEventCircleGesture->SetGesture(Leap::CircleGesture(Gesture));
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_CircleGestureDetected(EventDelegate, PEventCircleGesture);
			});
			PEventGesture = PEventCircleGesture;
			break;
		case Leap::Gesture::TYPE_KEY_TAP:
			if (PEventKeyTapGesture == nullptr)
			{
				PEventKeyTapGesture = NewObject<ULeapKeyTapGesture>();
				PEventKeyTapGesture->AddToRoot();
			}
			PEventKeyTapGesture->SetGesture(Leap::KeyTapGesture(Gesture));
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_KeyTapGestureDetected(EventDelegate, PEventKeyTapGesture);
			});
			PEventGesture = PEventKeyTapGesture;
			break;
		case Leap::Gesture::TYPE_SCREEN_TAP:
			if (PEventScreenTapGesture == nullptr)
			{
				PEventScreenTapGesture = NewObject<ULeapScreenTapGesture>();
				PEventScreenTapGesture->AddToRoot();
			}
			PEventScreenTapGesture->SetGesture(Leap::ScreenTapGesture(Gesture));
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_ScreenTapGestureDetected(EventDelegate, PEventScreenTapGesture);
			});
			PEventGesture = PEventScreenTapGesture;
			break;
		case Leap::Gesture::TYPE_SWIPE:
			if (PEventSwipeGesture == nullptr)
			{
				PEventSwipeGesture = NewObject<ULeapSwipeGesture>();
				PEventSwipeGesture->AddToRoot();
			}
			PEventSwipeGesture->SetGesture(Leap::SwipeGesture(Gesture));
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_SwipeGestureDetected(EventDelegate, PEventSwipeGesture);
			});
			PEventGesture = PEventSwipeGesture;
			break;
		default:
			break;
		}

		//emit gesture
		if (Type != Leap::Gesture::TYPE_INVALID)
		{
			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_GestureDetected(EventDelegate, PEventGesture);
			});
		}
	}

	//Image
	if (ControllerData.bAllowImageEvents && ControllerData.bImageEventsEnabled)
	{
		int ImageCount = Frame.images().count();

		//We only support getting both images
		if (ImageCount >= 2)
		{
			Leap::Image Image1 = Frame.images()[0];
			if (PEventImage1 == nullptr)
			{
				PEventImage1 = NewObject<ULeapImage>();
				PEventImage1->AddToRoot();
			}
			PEventImage1->UseGammaCorrection = ControllerData.bUseGammaCorrection;
			PEventImage1->SetLeapImage(Image1);

			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_RawImageReceived(EventDelegate, PEventImage1->Texture(), PEventImage1);
			});

			Leap::Image Image2 = Frame.images()[1];
			if (PEventImage2 == nullptr)
			{
				PEventImage2 = NewObject<ULeapImage>();
				PEventImage2->AddToRoot();
			}
			PEventImage2->UseGammaCorrection = ControllerData.bUseGammaCorrection;
			PEventImage2->SetLeapImage(Image2);

			CallFunctionOnDelegates([&](UObject* EventDelegate)
			{
				ILeapEventInterface::Execute_RawImageReceived(EventDelegate, PEventImage2->Texture(), PEventImage2);
			});
		}
	}
}