Support building for Magic Leap.

This commit is contained in:
Alan Jeffrey 2018-09-12 17:21:51 -05:00
parent e580250d5d
commit dab8f4a97f
34 changed files with 1601 additions and 7 deletions

View file

@ -0,0 +1,48 @@
// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
//
// THE CONTENTS OF THIS FILE IS GENERATED BY CODE AND
// ANY MODIFICATIONS WILL BE OVERWRITTEN
//
// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
// %BANNER_BEGIN%
// ---------------------------------------------------------------------
// %COPYRIGHT_BEGIN%
//
// Copyright (c) 2018 Magic Leap, Inc. All Rights Reserved.
// Use of this file is governed by the Creator Agreement, located
// here: https://id.magicleap.com/creator-terms
//
// %COPYRIGHT_END%
// ---------------------------------------------------------------------
// %BANNER_END%
#pragma once
#include <string>
#include <map>
// data class
class SceneDescriptor {
public:
typedef std::map<std::string /* exportedNodeName */, const std::string& /* exportedNodeId */> ExportedNodeReferences;
SceneDescriptor(const char* exportedName, const char* id, const char* sceneGraphFilePath, const char* resourceModelFilePath, const ExportedNodeReferences& exportedNodeReferences, bool initiallyInstanced);
const std::string& getExportedName() const;
const std::string& getId() const;
const std::string& getSceneGraphPath() const;
const std::string& getResourceModelPath() const;
const ExportedNodeReferences & getExportedNodeReferences() const;
bool getInitiallyInstanced() const;
private:
std::string exportedName_;
std::string id_;
std::string sceneGraphPath_;
std::string resourceModelPath_;
const ExportedNodeReferences& exportedNodeReferences_;
bool initiallyInstanced_;
};
typedef std::map<std::string /* exportedName */, const SceneDescriptor&> SceneDescriptorReferences;

View file

@ -0,0 +1,34 @@
// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
//
// THE CONTENTS OF THIS FILE IS GENERATED BY CODE AND
// ANY MODIFICATIONS WILL BE OVERWRITTEN
//
// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
// %BANNER_BEGIN%
// ---------------------------------------------------------------------
// %COPYRIGHT_BEGIN%
//
// Copyright (c) 2018 Magic Leap, Inc. All Rights Reserved.
// Use of this file is governed by the Creator Agreement, located
// here: https://id.magicleap.com/creator-terms
//
// %COPYRIGHT_END%
// ---------------------------------------------------------------------
// %BANNER_END%
#pragma once
#include <SceneDescriptor.h>
namespace Servo2D_exportedNodes {
extern const std::string content;
extern const std::string backButton;
extern const std::string fwdButton;
extern const std::string urlBar;
}
namespace scenes {
extern const SceneDescriptor Servo2D;
extern const SceneDescriptorReferences exportedScenes;
}

View file

@ -0,0 +1,96 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <lumin/LandscapeApp.h>
#include <lumin/Prism.h>
#include <lumin/event/ServerEvent.h>
#include <lumin/resource/PlanarResource.h>
#include <SceneDescriptor.h>
typedef void* ServoInstance;
/**
* Servo2D Landscape Application
*/
class Servo2D : public lumin::LandscapeApp {
public:
/**
* Constructs the Landscape Application.
*/
Servo2D();
/**
* Destroys the Landscape Application.
*/
virtual ~Servo2D();
/**
* Disallows the copy constructor.
*/
Servo2D(const Servo2D&) = delete;
/**
* Disallows the move constructor.
*/
Servo2D(Servo2D&&) = delete;
/**
* Disallows the copy assignment operator.
*/
Servo2D& operator=(const Servo2D&) = delete;
/**
* Disallows the move assignment operator.
*/
Servo2D& operator=(Servo2D&&) = delete;
protected:
/**
* Initializes the Landscape Application.
* @return - 0 on success, error code on failure.
*/
int init() override;
/**
* Deinitializes the Landscape Application.
* @return - 0 on success, error code on failure.
*/
int deInit() override;
/**
* Returns the size of the Prism, default = +/- (1.0f, 1.0f, 1.0f) meters.
* Used in createPrism().
*/
const glm::vec3 getInitialPrismExtents() const;
/**
* Creates the prism, updates the private variable prism_ with the created prism.
*/
int createInitialPrism();
/**
* Initializes and creates the scene of all scenes marked as initially instanced
*/
void instanceInitialScenes();
/**
* Initializes and creates the scene of the scene and instances it into the prism
*/
lumin::Node* instanceScene(const SceneDescriptor & sceneToInit);
/**
* Run application login
*/
virtual bool updateLoop(float fDelta) override;
/**
* Handle events from the server
*/
virtual bool eventListener(lumin::ServerEvent* event) override;
private:
lumin::Prism* prism_ = nullptr; // represents the bounded space where the App renders.
lumin::PlanarResource* plane_ = nullptr; // the plane we're rendering into
ServoInstance servo_ = nullptr; // the servo instance we're embedding
};

View file

@ -0,0 +1,54 @@
// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
//
// THE CONTENTS OF THIS FILE IS GENERATED BY CODE AND
// ANY MODIFICATIONS WILL BE OVERWRITTEN
//
// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
// %BANNER_BEGIN%
// ---------------------------------------------------------------------
// %COPYRIGHT_BEGIN%
//
// Copyright (c) 2018 Magic Leap, Inc. All Rights Reserved.
// Use of this file is governed by the Creator Agreement, located
// here: https://id.magicleap.com/creator-terms
//
// %COPYRIGHT_END%
// ---------------------------------------------------------------------
// %BANNER_END%
#include <SceneDescriptor.h>
SceneDescriptor::SceneDescriptor(const char * exportedName, const char * id, const char * sceneGraphPath, const char * resourceModelPath, const ExportedNodeReferences& exportedNodeReferences, bool initiallyInstanced)
:
exportedName_(exportedName),
id_(id),
sceneGraphPath_(sceneGraphPath),
resourceModelPath_(resourceModelPath),
exportedNodeReferences_(exportedNodeReferences),
initiallyInstanced_(initiallyInstanced) {
}
const std::string & SceneDescriptor::getExportedName() const {
return exportedName_;
}
const std::string & SceneDescriptor::getId() const {
return id_;
}
const std::string & SceneDescriptor::getSceneGraphPath() const {
return sceneGraphPath_;
}
const std::string & SceneDescriptor::getResourceModelPath() const {
return resourceModelPath_;
}
const SceneDescriptor::ExportedNodeReferences & SceneDescriptor::getExportedNodeReferences() const {
return exportedNodeReferences_;
}
bool SceneDescriptor::getInitiallyInstanced() const {
return initiallyInstanced_;
}

View file

@ -0,0 +1,49 @@
// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
//
// THE CONTENTS OF THIS FILE IS GENERATED BY CODE AND
// ANY MODIFICATIONS WILL BE OVERWRITTEN
//
// -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING -- WARNING --
// %BANNER_BEGIN%
// ---------------------------------------------------------------------
// %COPYRIGHT_BEGIN%
//
// Copyright (c) 2018 Magic Leap, Inc. All Rights Reserved.
// Use of this file is governed by the Creator Agreement, located
// here: https://id.magicleap.com/creator-terms
//
// %COPYRIGHT_END%
// ---------------------------------------------------------------------
// %BANNER_END%
#include <scenesGen.h>
namespace Servo2D_exportedNodes {
const std::string content = "content";
const std::string backButton = "backButton";
const std::string fwdButton = "fwdButton";
const std::string urlBar = "urlBar";
}
namespace scenes {
const SceneDescriptor::ExportedNodeReferences Servo2D_exportedNodesMap = {
{"content", Servo2D_exportedNodes::content},
{"backButton", Servo2D_exportedNodes::backButton},
{"fwdButton", Servo2D_exportedNodes::fwdButton},
{"urlBar", Servo2D_exportedNodes::urlBar}
};
const SceneDescriptor Servo2D(
"Servo2D",
"root",
"/assets/scenes/scenes/Servo2D.scene.xml",
"/assets/scenes/scenes/Servo2D.scene.res.xml",
Servo2D_exportedNodesMap,
true);
const SceneDescriptorReferences exportedScenes = {
{Servo2D.getExportedName(), Servo2D}
};
}

View file

@ -0,0 +1,200 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <Servo2D.h>
#include <lumin/node/RootNode.h>
#include <lumin/node/QuadNode.h>
#include <lumin/ui/Cursor.h>
#include <ml_logging.h>
#include <scenesGen.h>
#include <SceneDescriptor.h>
#include <EGL/egl.h>
#include <GLES/gl.h>
#include <string.h>
// The viewport dimensions (in px).
const unsigned int VIEWPORT_W = 500;
const unsigned int VIEWPORT_H = 500;
// The hidpi factor.
const float HIDPI = 1.0;
// The prism dimensions (in m).
const float PRISM_W = 0.5;
const float PRISM_H = 0.5;
const float PRISM_D = 0.5;
// A function which calls the ML logger, suitable for passing into Servo
typedef void (*MLLogger)(MLLogLevel lvl, char* msg);
void logger(MLLogLevel lvl, char* msg) {
if (MLLoggingLogLevelIsEnabled(lvl)) {
MLLoggingLog(lvl, ML_DEFAULT_LOG_TAG, msg);
}
}
// The functions Servo provides for hooking up to the ML.
// For the moment, this doesn't handle input events.
extern "C" ServoInstance init_servo(EGLContext, EGLSurface, EGLDisplay, MLLogger,
const char* url, int width, int height, float hidpi);
extern "C" void heartbeat_servo(ServoInstance);
extern "C" void discard_servo(ServoInstance);
// Create a Servo2D instance
Servo2D::Servo2D() {
ML_LOG(Debug, "Servo2D Constructor.");
}
// Destroy a Servo 2D instance
Servo2D::~Servo2D() {
ML_LOG(Debug, "Servo2D Destructor.");
discard_servo(servo_);
servo_ = nullptr;
}
// The prism dimensions
const glm::vec3 Servo2D::getInitialPrismExtents() const {
return glm::vec3(PRISM_W, PRISM_H, PRISM_D);
}
// Create the prism for Servo
int Servo2D::createInitialPrism() {
prism_ = requestNewPrism(getInitialPrismExtents());
if (!prism_) {
ML_LOG(Error, "Servo2D Error creating default prism.");
return 1;
}
return 0;
}
// Initialize a Servo instance
int Servo2D::init() {
ML_LOG(Debug, "Servo2D Initializing.");
// Set up the prism
createInitialPrism();
lumin::ui::Cursor::SetScale(prism_, 0.03f);
instanceInitialScenes();
// Get the planar resource that holds the EGL context
lumin::RootNode* root_node = prism_->getRootNode();
if (!root_node) {
ML_LOG(Error, "Servo2D Failed to get root node");
abort();
return 1;
}
std::string content_node_id = Servo2D_exportedNodes::content;
lumin::QuadNode* content_node = lumin::QuadNode::CastFrom(prism_->findNode(content_node_id, root_node));
if (!content_node) {
ML_LOG(Error, "Servo2D Failed to get content node");
abort();
return 1;
}
lumin::ResourceIDType plane_id = prism_->createPlanarEGLResourceId();
if (!plane_id) {
ML_LOG(Error, "Servo2D Failed to create EGL resource");
abort();
return 1;
}
plane_ = static_cast<lumin::PlanarResource*>(prism_->getResource(plane_id));
if (!plane_) {
ML_LOG(Error, "Servo2D Failed to create plane");
abort();
return 1;
}
content_node->setRenderResource(plane_id);
// Get the EGL context, surface and display.
EGLContext ctx = plane_->getEGLContext();
EGLSurface surf = plane_->getEGLSurface();
EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglMakeCurrent(dpy, surf, surf, ctx);
glViewport(0, 0, VIEWPORT_W, VIEWPORT_H);
// Hook into servo
servo_ = init_servo(ctx, surf, dpy, logger, "https://servo.org", VIEWPORT_H, VIEWPORT_W, HIDPI);
if (!servo_) {
ML_LOG(Error, "Servo2D Failed to init servo instance");
abort();
return 1;
}
// Flush GL
glFlush();
eglSwapBuffers(dpy, surf);
return 0;
}
int Servo2D::deInit() {
ML_LOG(Debug, "Servo2D Deinitializing.");
return 0;
}
lumin::Node* Servo2D::instanceScene(const SceneDescriptor& scene) {
// Load resources.
if (!prism_->loadResourceModel(scene.getResourceModelPath())) {
ML_LOG(Info, "No resource model loaded");
}
// Load a scene file.
std::string editorObjectModelName;
if (!prism_->loadObjectModel(scene.getSceneGraphPath(), editorObjectModelName)) {
ML_LOG(Error, "Servo2D Failed to load object model");
abort();
return nullptr;
}
// Add scene to this prism.
lumin::Node* newTree = prism_->createAll(editorObjectModelName);
if (!prism_->getRootNode()->addChild(newTree)) {
ML_LOG(Error, "Servo2D Failed to add newTree to the prism root node");
abort();
return nullptr;
}
return newTree;
}
void Servo2D::instanceInitialScenes() {
// Iterate over all the exported scenes
for (auto& exportedSceneEntry : scenes::exportedScenes ) {
// If this scene was marked to be instanced at app initialization, do it
const SceneDescriptor &sd = exportedSceneEntry.second;
if (sd.getInitiallyInstanced()) {
instanceScene(sd);
}
}
}
bool Servo2D::updateLoop(float fDelta) {
// Get the EGL context, surface and display.
EGLContext ctx = plane_->getEGLContext();
EGLSurface surf = plane_->getEGLSurface();
EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglMakeCurrent(dpy, surf, surf, ctx);
glViewport(0, 0, VIEWPORT_W, VIEWPORT_H);
// Hook into servo
heartbeat_servo(servo_);
// Flush GL
glFlush();
eglSwapBuffers(dpy, surf);
// Return true for your app to continue running, false to terminate the app.
return true;
}
bool Servo2D::eventListener(lumin::ServerEvent* event) {
// Place your event handling here.
// Return true if the event is consumed.
return false;
}

View file

@ -0,0 +1,13 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <Servo2D.h>
#include <ml_logging.h>
int main(int argc, char **argv)
{
ML_LOG(Debug, "Servo2D Starting.");
Servo2D myApp;
return myApp.run();
}

View file

@ -0,0 +1,3 @@
SRCS = \
src.gen/scenesGen.cpp \
src.gen/SceneDescriptor.cpp \