EddyVerbruggen / nativescript-ar

Augmented Reality NativeScript plugin
https://www.nativescript.org/blog/preview-of-augmented-reality-in-nativescript
MIT License
118 stars 36 forks source link

Add a SolarSystem demo, in NativeScript-Vue #41

Closed EddyVerbruggen closed 5 years ago

EddyVerbruggen commented 5 years ago

Try to replicate the Android Solar system demo for iOS and Android in NativeScript.

And we need a Vue demo as well, so that seems like a good opportunity.

EddyVerbruggen commented 5 years ago

Added scaffolding - no implementation yet.

nickolanack commented 5 years ago

for the controls panel in solarsystem, (ie adUIView) it would be nice to have a faceCamera/lookAt method although all nodes would benefit from this

nickolanack commented 5 years ago

Here is my pure js solarsystem demo. it doesn't have the controls panel and no materials... also using empty nodes (ar.addNode) for orbits. A bit rough, but it's a start...

var solarSystemDefinition = {
    name: "Sun",
    distance: 0,
    orbitSpeed: 0,
    model: "Sol.sfb",
    scale: 0.5,
    materials: [new Color("Coral")],
    tilt: 0,
    children: [{
        name: "Mercury",
        distance: 0.4,
        orbitSpeed: 47,
        model: "Mercury.sfb",
        scale: 0.019,
        tilt: 0.03
    }, {
        name: "Venus",
        distance: 0.7,
        orbitSpeed: 35,
        model: "Venus.sfb",
        scale: 0.0475,
        tilt: 2.64
    }, {
        name: "Earth",
        distance: 1.0,
        orbitSpeed: 29,
        model: "Earth.sfb",
        scale: 0.05,
        tilt: 23.4,
        materials: [new Color("Blue")],
        children: [{
            name: "Moon",
            distance: 0.15,
            orbitSpeed: 100,
            model: "Luna.sfb",
            scale: 0.018,
            tilt: 6.68,
            materials: [new Color("Gray")],
        }]
    }, {
        name: "Mars",
        distance: 1.5,
        orbitSpeed: 24,
        model: "Mars.sfb",
        scale: 0.0265,
        tilt: 25.19
    }, {
        name: "Jupiter",
        distance: 2.2,
        orbitSpeed: 13,
        model: "Jupiter.sfb",
        scale: 0.16,
        tilt: 3.13
    }, {
        name: "Saturn",
        distance: 3.5,
        orbitSpeed: 9,
        model: "Saturn.sfb",
        scale: 0.1325,
        tilt: 26.73
    }, {
        name: "Uranus",
        distance: 5.2,
        orbitSpeed: 7,
        model: "Uranus.sfb",
        scale: 0.1,
        tilt: 82.23
    }, {
        name: "Neptune",
        distance: 6.1,
        orbitSpeed: 5,
        model: "Neptune.sfb",
        scale: 0.074,
        tilt: 28.32
    }]
};

var fps = 60;
var orbitals = [];
var animator = setInterval(function() {

    orbitals.forEach(function(orbit) {

        orbit.node.rotateBy({
            x: 0,
            y: orbit.speed / fps,
            z: 0
        });

    });

}, 1000 / fps);

var renderSolarsystemObj = function(object, parentNode) {

    ar.addNode({
        parentNode: parentNode,

        rotation: {
            x: 0,
            y: 0,
            z: object.tilt
        },
    }).then(function(orbitNode) {

        orbitals.push({
            node: orbitNode,
            speed: object.orbitSpeed
        });

        ar.addNode({

            position: {
                x: 0,
                y: 0,
                z: -object.distance
            },
            parentNode: orbitNode,

        }).then(function(objectNode) {

            ar.addModel({
                parentNode: objectNode,
                scale: object.scale,
                name: object.model
            }).catch(function() {
                console.error(e);
            });

            if (object.children) {
                object.children.forEach(function(child) {
                    renderSolarsystemObj(child, objectNode);
                });
            }

        }).catch(function(e) {
            console.error(e);
        })

    }).catch(function(e) {
        console.error(e);
    })

};

ar.addNode({
    position: {
        x: 0,
        y: 0,
        z: -1
    },
    scale: 1,
}).then(function(solarSystemNode) {
    renderSolarsystemObj(solarSystemDefinition, solarSystemNode)
})
nickolanack commented 5 years ago

I mixed up orbital inclination, with axial tilt...

EddyVerbruggen commented 5 years ago

Currently working on this, thanks for the example code!

EddyVerbruggen commented 5 years ago

@nickolanack If you want to see your sample code in action then please update the repo and run npm run demo.solarsystem.android (not working for iOS yet)!

nickolanack commented 5 years ago

oh nice!. I'm excited to check this out.

EddyVerbruggen commented 5 years ago

Cool, please do! I've now added the view to control the speed of orbit and rotation when you tap the sun. ☀

nickolanack commented 5 years ago

thats awesome! good work!

EddyVerbruggen commented 5 years ago

Cheers! I'll try and add iOS support as well. Not sure which angle to take here.. we could simply use spheres and materials as fi. used here, or try and find models for all these celestial bodies. If we go the sphere-route we might as well use that for Android as well so it's more x-platform-y ;)

nickolanack commented 5 years ago

The original android models were gltf models but contain diffuse, normal map, and metallic maps as pngs - so it should be easy to just use those images with spheres (with the json material definition (like the iOS demo box)

EddyVerbruggen commented 5 years ago

Yes, that would be perfect!

EddyVerbruggen commented 5 years ago

@nickolanack It's worth updating your code and running this demo again. We're now using spheres instead of models and share the same textures on both platforms (although you have to duplicate them in the respective resource folders, but that's not a big issue imo).

There are a few annoying differences in behavior between the platforms. Perhaps you have an idea fi why the rotation controls (tap the sun to reveal them) don't work on iOS.

And we should find a way to make the ui views (like the aforementioned controls) always face the user. I think you mentioned something about this before.

nickolanack commented 5 years ago

That’s awesome

nickolanack commented 5 years ago

I have written code to point a node at the camera I can clean it up an PR shortly (node.lookAt(camera))

nickolanack commented 5 years ago

@EddyVerbruggen the IOS control panel is clipped for me, is that also the case for you?

nickolanack commented 5 years ago

On android when stacking spheres, the inner sphere seems to get culled, this appears to be solvable by setting render priority on the inner sphere: (previously i adjusted the outer sphere center ie {x:0.0001,y:0,z:0} and that seemed to help but this works better:

if(o.android){
    o.android.getRenderable().setRenderPriority(3); //(default is 4)
}
nickolanack commented 5 years ago

btw sun solarflares are similar to saturns rings... Screen Shot 2019-09-02 at 11 14 31 PM just randomly placed planes with image

EddyVerbruggen commented 5 years ago

@nickolanack That hint https://github.com/EddyVerbruggen/nativescript-ar/issues/41#issuecomment-527308848 seems to work pretty well for me! I've integrated it here:

https://github.com/EddyVerbruggen/nativescript-ar/blob/094f72c2a80fc1e1db14d5fc6dd059c702ef786c/src/ar.android.ts#L88-L101

EddyVerbruggen commented 5 years ago

I'm quite happy with this as it stands, so closing. I'll clean up the models we used for the Android model approach we had at first.