I’ve struggled with this for about a week: make a component that should display a SceneKit view, and would work in both iOS and MacOS builds, and could be used with other components. I have now achieved that and wanted to share the “wisdom”.
Add the following to “Extra System Frameworks” in iOS/MacOS exporters (choose the ones you want): Metal, SceneKit, MetalKit
If you want to display the assets from the default SceneKit “Game” project, copy “art.sncassets” folder into your “Source” folder, and then add “Source/art.scnassets” to “Custom Xcode Resource Folders” in iOS/MacOS exporters (for some reason, it doesn’t work if you don’t place the assets folder under “Source”).
Create new .h/.cpp file pair in Juicer, and rename .cpp file into .mm file. Let’s say you named these SceneKitControl.h and SceneKitControl.mm.
SceneKitControl.h:
#pragma once
#include "../JuceLibraryCode/JuceHeader.h"
#if JUCE_IOS
#define SceneKitBase UIViewComponent
#endif
#if JUCE_MAC
#define SceneKitBase NSViewComponent
#endif
class SceneKitControl : public SceneKitBase
{
public:
SceneKitControl ();
void
resized () override;
private:
void*
m_view = nullptr;
};
SceneKitControl.mm:
#include <SceneKit/SCNView.h>
#include <SceneKit/SCNScene.h>
#include "SceneKitControl.h"
SceneKitControl::SceneKitControl ()
{
// nothing for now
}
void
SceneKitControl::resized ()
{
if (!m_view)
{
const auto b = getLocalBounds ();
if (!b.isEmpty())
{
CGRect rect;
rect.origin.x = b.getX();
rect.origin.y = b.getY();
rect.size.height = b.getHeight();
rect.size.width = b.getWidth();
SCNView* view = [[SCNView alloc] initWithFrame:rect];
view.allowsCameraControl = true;
view.showsStatistics = true;
NSString *name = @"art.scnassets/ship.scn";
SCNScene* scene = [SCNScene sceneNamed:name];
view.scene = scene;
m_view = view;
setView (view);
}
}
}
How you can use this component anywhere in your iOS/MacOS app.
You can see the result here (Instagram video).
