mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 1306415 - Part 1: Implement VRFrameData and VRDisplay.getFrameData,r=smaug,r=dmu
MozReview-Commit-ID: HlZUtZ7iZb5 --HG-- extra : rebase_source : 2d5de1522c0b06aa49d5a0ad3fe2170fff78ec37
This commit is contained in:
parent
43c76f1bba
commit
423a243482
@ -303,6 +303,20 @@ VRPose::VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
|
||||
VRPose::VRPose(nsISupports* aParent)
|
||||
: mParent(aParent)
|
||||
, mPosition(nullptr)
|
||||
, mLinearVelocity(nullptr)
|
||||
, mLinearAcceleration(nullptr)
|
||||
, mOrientation(nullptr)
|
||||
, mAngularVelocity(nullptr)
|
||||
, mAngularAcceleration(nullptr)
|
||||
{
|
||||
mFrameId = 0;
|
||||
mVRState.Clear();
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
|
||||
VRPose::~VRPose()
|
||||
{
|
||||
mozilla::DropJSObjects(this);
|
||||
@ -490,6 +504,15 @@ VRDisplay::GetStageParameters()
|
||||
return mStageParameters;
|
||||
}
|
||||
|
||||
bool
|
||||
VRDisplay::GetFrameData(VRFrameData& aFrameData)
|
||||
{
|
||||
gfx::VRHMDSensorState state = mClient->GetSensorState();
|
||||
const gfx::VRDisplayInfo& info = mClient->GetDisplayInfo();
|
||||
aFrameData.Update(info, state, mDepthNear, mDepthFar);
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<VRPose>
|
||||
VRDisplay::GetPose()
|
||||
{
|
||||
@ -658,5 +681,174 @@ NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, DOMEventTargetHelper)
|
||||
NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(VRFrameData)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(VRFrameData)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent, mPose)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
tmp->mLeftProjectionMatrix = nullptr;
|
||||
tmp->mLeftViewMatrix = nullptr;
|
||||
tmp->mRightProjectionMatrix = nullptr;
|
||||
tmp->mRightViewMatrix = nullptr;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(VRFrameData)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent, mPose)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(VRFrameData)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLeftProjectionMatrix)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mLeftViewMatrix)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mRightProjectionMatrix)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mRightViewMatrix)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFrameData, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFrameData, Release)
|
||||
|
||||
VRFrameData::VRFrameData(nsISupports* aParent)
|
||||
: mParent(aParent)
|
||||
, mLeftProjectionMatrix(nullptr)
|
||||
, mLeftViewMatrix(nullptr)
|
||||
, mRightProjectionMatrix(nullptr)
|
||||
, mRightViewMatrix(nullptr)
|
||||
{
|
||||
mPose = new VRPose(aParent);
|
||||
}
|
||||
|
||||
VRFrameData::~VRFrameData()
|
||||
{
|
||||
mozilla::DropJSObjects(this);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<VRFrameData>
|
||||
VRFrameData::Constructor(const GlobalObject& aGlobal, ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<VRFrameData> obj = new VRFrameData(aGlobal.GetAsSupports());
|
||||
return obj.forget();
|
||||
}
|
||||
|
||||
JSObject*
|
||||
VRFrameData::WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return VRFrameDataBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
VRPose*
|
||||
VRFrameData::Pose()
|
||||
{
|
||||
return mPose;
|
||||
}
|
||||
|
||||
void
|
||||
VRFrameData::LazyCreateMatrix(JS::Heap<JSObject*>& aArray, gfx::Matrix4x4& aMat, JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval, ErrorResult& aRv)
|
||||
{
|
||||
if (!aArray) {
|
||||
// Lazily create the Float32Array
|
||||
aArray = dom::Float32Array::Create(aCx, this, 16, aMat.components);
|
||||
if (!aArray) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (aArray) {
|
||||
JS::ExposeObjectToActiveJS(aArray);
|
||||
}
|
||||
aRetval.set(aArray);
|
||||
}
|
||||
|
||||
double
|
||||
VRFrameData::Timestamp() const
|
||||
{
|
||||
return mVRState.timestamp * 1000.0f; // Converting from seconds to milliseconds
|
||||
}
|
||||
|
||||
void
|
||||
VRFrameData::GetLeftProjectionMatrix(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
LazyCreateMatrix(mLeftProjectionMatrix, mLeftProjection, aCx, aRetval, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
VRFrameData::GetLeftViewMatrix(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
LazyCreateMatrix(mLeftViewMatrix, mLeftView, aCx, aRetval, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
VRFrameData::GetRightProjectionMatrix(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
LazyCreateMatrix(mRightProjectionMatrix, mRightProjection, aCx, aRetval, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
VRFrameData::GetRightViewMatrix(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
LazyCreateMatrix(mRightViewMatrix, mRightView, aCx, aRetval, aRv);
|
||||
}
|
||||
|
||||
void
|
||||
VRFrameData::Update(const gfx::VRDisplayInfo& aInfo,
|
||||
const gfx::VRHMDSensorState& aState,
|
||||
float aDepthNear,
|
||||
float aDepthFar)
|
||||
{
|
||||
mVRState = aState;
|
||||
|
||||
mLeftProjectionMatrix = nullptr;
|
||||
mLeftViewMatrix = nullptr;
|
||||
mRightProjectionMatrix = nullptr;
|
||||
mRightViewMatrix = nullptr;
|
||||
|
||||
mPose = new VRPose(GetParentObject(), aState);
|
||||
|
||||
gfx::Quaternion qt;
|
||||
if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
|
||||
qt.x = mVRState.orientation[0];
|
||||
qt.y = mVRState.orientation[1];
|
||||
qt.z = mVRState.orientation[2];
|
||||
qt.w = mVRState.orientation[3];
|
||||
}
|
||||
gfx::Point3D pos;
|
||||
if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
|
||||
pos.x = -mVRState.position[0];
|
||||
pos.y = -mVRState.position[1];
|
||||
pos.z = -mVRState.position[2];
|
||||
}
|
||||
gfx::Matrix4x4 matHead;
|
||||
matHead.SetRotationFromQuaternion(qt);
|
||||
matHead.PreTranslate(pos);
|
||||
|
||||
mLeftView = matHead;
|
||||
mLeftView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Left]);
|
||||
|
||||
mRightView = matHead;
|
||||
mRightView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Right]);
|
||||
|
||||
// Avoid division by zero within ConstructProjectionMatrix
|
||||
const float kEpsilon = 0.00001f;
|
||||
if (fabs(aDepthFar - aDepthNear) < kEpsilon) {
|
||||
aDepthFar = aDepthNear + kEpsilon;
|
||||
}
|
||||
|
||||
const gfx::VRFieldOfView leftFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Left];
|
||||
mLeftProjection = leftFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
|
||||
const gfx::VRFieldOfView rightFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Right];
|
||||
mRightProjection = rightFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
|
||||
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -100,6 +100,7 @@ class VRPose final : public nsWrapperCache
|
||||
|
||||
public:
|
||||
VRPose(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
|
||||
explicit VRPose(nsISupports* aParent);
|
||||
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRPose)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRPose)
|
||||
@ -144,6 +145,63 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
class VRFrameData final : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFrameData)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFrameData)
|
||||
|
||||
explicit VRFrameData(nsISupports* aParent);
|
||||
static already_AddRefed<VRFrameData> Constructor(const GlobalObject& aGlobal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void Update(const gfx::VRDisplayInfo& aInfo,
|
||||
const gfx::VRHMDSensorState& aState,
|
||||
float aDepthNear,
|
||||
float aDepthFar);
|
||||
|
||||
// WebIDL Members
|
||||
double Timestamp() const;
|
||||
void GetLeftProjectionMatrix(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
void GetLeftViewMatrix(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
void GetRightProjectionMatrix(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
void GetRightViewMatrix(JSContext* aCx,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
|
||||
VRPose* Pose();
|
||||
|
||||
// WebIDL Boilerplate
|
||||
nsISupports* GetParentObject() const { return mParent; }
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
protected:
|
||||
~VRFrameData();
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
||||
gfx::VRHMDSensorState mVRState;
|
||||
RefPtr<VRPose> mPose;
|
||||
JS::Heap<JSObject*> mLeftProjectionMatrix;
|
||||
JS::Heap<JSObject*> mLeftViewMatrix;
|
||||
JS::Heap<JSObject*> mRightProjectionMatrix;
|
||||
JS::Heap<JSObject*> mRightViewMatrix;
|
||||
|
||||
gfx::Matrix4x4 mLeftProjection;
|
||||
gfx::Matrix4x4 mLeftView;
|
||||
gfx::Matrix4x4 mRightProjection;
|
||||
gfx::Matrix4x4 mRightView;
|
||||
|
||||
void LazyCreateMatrix(JS::Heap<JSObject*>& aArray, gfx::Matrix4x4& aMat,
|
||||
JSContext* aCx, JS::MutableHandle<JSObject*> aRetval,
|
||||
ErrorResult& aRv);
|
||||
};
|
||||
|
||||
class VRStageParameters final : public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
@ -235,6 +293,7 @@ public:
|
||||
|
||||
virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye);
|
||||
|
||||
bool GetFrameData(VRFrameData& aFrameData);
|
||||
already_AddRefed<VRPose> GetPose();
|
||||
already_AddRefed<VRPose> GetImmediatePose();
|
||||
void ResetPose();
|
||||
|
@ -133,6 +133,21 @@ interface VRPose {
|
||||
[Constant, Throws] readonly attribute Float32Array? angularAcceleration;
|
||||
};
|
||||
|
||||
[Constructor,
|
||||
Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDisplay.h"]
|
||||
interface VRFrameData {
|
||||
readonly attribute DOMHighResTimeStamp timestamp;
|
||||
|
||||
[Throws, Pure] readonly attribute Float32Array leftProjectionMatrix;
|
||||
[Throws, Pure] readonly attribute Float32Array leftViewMatrix;
|
||||
|
||||
[Throws, Pure] readonly attribute Float32Array rightProjectionMatrix;
|
||||
[Throws, Pure] readonly attribute Float32Array rightViewMatrix;
|
||||
|
||||
[Pure] readonly attribute VRPose pose;
|
||||
};
|
||||
|
||||
[Pref="dom.vr.enabled",
|
||||
HeaderFile="mozilla/dom/VRDisplay.h"]
|
||||
interface VREyeParameters {
|
||||
@ -187,6 +202,12 @@ interface VRDisplay : EventTarget {
|
||||
*/
|
||||
[Constant] readonly attribute DOMString displayName;
|
||||
|
||||
/**
|
||||
* Populates the passed VRFrameData with the information required to render
|
||||
* the current frame.
|
||||
*/
|
||||
boolean getFrameData(VRFrameData frameData);
|
||||
|
||||
/**
|
||||
* Return a VRPose containing the future predicted pose of the VRDisplay
|
||||
* when the current frame will be presented. Subsequent calls to getPose()
|
||||
|
@ -23,7 +23,8 @@ VRDisplayManager::AllocateDisplayID()
|
||||
}
|
||||
|
||||
Matrix4x4
|
||||
VRFieldOfView::ConstructProjectionMatrix(float zNear, float zFar, bool rightHanded)
|
||||
VRFieldOfView::ConstructProjectionMatrix(float zNear, float zFar,
|
||||
bool rightHanded) const
|
||||
{
|
||||
float upTan = tan(upDegrees * M_PI / 180.0);
|
||||
float downTan = tan(downDegrees * M_PI / 180.0);
|
||||
|
@ -112,7 +112,7 @@ struct VRFieldOfView {
|
||||
leftDegrees == 0.0;
|
||||
}
|
||||
|
||||
Matrix4x4 ConstructProjectionMatrix(float zNear, float zFar, bool rightHanded);
|
||||
Matrix4x4 ConstructProjectionMatrix(float zNear, float zFar, bool rightHanded) const;
|
||||
|
||||
double upDegrees;
|
||||
double rightDegrees;
|
||||
|
Loading…
Reference in New Issue
Block a user