Jump to content

Babylon.js in Adobe CEP


anycast
 Share

Recommended Posts

Hi,

I'm doing an Adobe extension using Adobe CEP (Common Extensibility Platform). Adobe CEP uses CEF to enable HTML5 content within an Adobe application, so any HTML/Javascript code within it should behave just as in a browser.

I've created a simple extension by copy/pasting a babylonjs sample:

<!doctype html>
<!--
/*************************************************************************
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2014 Adobe
* All Rights Reserved.
*
* NOTICE: Adobe permits you to use, modify, and distribute this file in
* accordance with the terms of the Adobe license agreement accompanying
* it. If you have received this file from a source other than Adobe,
* then your use, modification, or distribution of it requires the prior
* written permission of Adobe. 
**************************************************************************/
-->
<html>
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/styles.css" />
    <link id="hostStyle" rel="stylesheet" href="css/theme.css" />
    <title></title>
    
    <style>
            html, body {
                overflow: hidden;
                width: 100%;
                height: 100%;
                margin: 0;
                padding: 0;
            }

            #renderCanvas {
                width: 100%;
                height: 100%;
                touch-action: none;
            }
        </style>

    <script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <script src="https://cdn.babylonjs.com/babylon.js"></script>

</head>

<body>

    <canvas id="renderCanvas" touch-action="none"></canvas>

    <script>
        var canvas = document.getElementById("renderCanvas"); // Get the canvas element
        var engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

        /******* Add the create scene function ******/
        var createScene = function () {

            // Create the scene space
            var scene = new BABYLON.Scene(engine);

            // Add a camera to the scene and attach it to the canvas
            var camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new BABYLON.Vector3(0,0,5), scene);
            camera.attachControl(canvas, true);

            // Add lights to the scene
            var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), scene);
            var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(0, 1, -1), scene);

            // Add and manipulate meshes in the scene
            var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter:6}, scene);

            return scene;
        };
        /******* End of the create scene function ******/

        var scene = createScene(); //Call the createScene function

        // Register a render loop to repeatedly render the scene
        engine.runRenderLoop(function () {
                scene.render();
        });

        // Watch for browser/canvas resize events
        window.addEventListener("resize", function () {
                engine.resize();
        });


        canvas.addEventListener("mouseup", function(){
            console.log("Mouse UP!");
        });

        canvas.addEventListener("mousedown", function(){
            console.log("Mouse DOWN!");
        });

        canvas.addEventListener("click", function(){
            console.log("Mouse Click!");
        });
    </script>


</body>
</html>

 

This displays what it's supposed to display (a sphere), but dragging the mouse on top of the canvas doesn't rotate the camera. Scrolling the mouse wheel zooms in/out as it's supposed to though. I've added some listeners for mouse events and they all work.

 

 

I tried doing something similar with threejs:

<!DOCTYPE html>
<html lang="en">
<head>
    <title>three.js webgl - orbit controls</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
    <style>
        body {
            color: #000;
            font-family: Monospace;
            font-size: 13px;
            text-align: center;
            font-weight: bold;
            background-color: #fff;
            margin: 0px;
            overflow: hidden;
        }

        #info {
            color: #000;
            position: absolute;
            top: 0px;
            width: 100%;
            padding: 5px;
        }

        a {
            color: red;
        }
    </style>
</head>
<body>
    <div id="info">
        <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - orbit controls example
    </div>
    <script src="js/three.js"></script>
    <script src="js/OrbitControls.js"></script>
    <script src="js/WebGL.js"></script>
    <script>if ( WEBGL.isWebGLAvailable() === false ) {
                document.body.appendChild( WEBGL.getWebGLErrorMessage() );
            }
            var camera, controls, scene, renderer;
            init();
            //render(); // remove when using next line for animation loop (requestAnimationFrame)
            animate();
            function init() {
                scene = new THREE.Scene();
                scene.background = new THREE.Color( 0xcccccc );
                scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 );
                renderer = new THREE.WebGLRenderer( { antialias: true } );
                renderer.setPixelRatio( window.devicePixelRatio );
                renderer.setSize( window.innerWidth, window.innerHeight );
                document.body.appendChild( renderer.domElement );
                camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
                camera.position.set( 400, 200, 0 );
                // controls
                controls = new THREE.OrbitControls( camera, renderer.domElement );
                //controls.addEventListener( 'change', render ); // call this only in static scenes (i.e., if there is no animation loop)
                controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
                controls.dampingFactor = 0.25;
                controls.screenSpacePanning = false;
                controls.minDistance = 100;
                controls.maxDistance = 500;
                controls.maxPolarAngle = Math.PI / 2;
                // world
                var geometry = new THREE.CylinderBufferGeometry( 0, 10, 30, 4, 1 );
                var material = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } );
                for ( var i = 0; i < 500; i ++ ) {
                    var mesh = new THREE.Mesh( geometry, material );
                    mesh.position.x = Math.random() * 1600 - 800;
                    mesh.position.y = 0;
                    mesh.position.z = Math.random() * 1600 - 800;
                    mesh.updateMatrix();
                    mesh.matrixAutoUpdate = false;
                    scene.add( mesh );
                }
                // lights
                var light = new THREE.DirectionalLight( 0xffffff );
                light.position.set( 1, 1, 1 );
                scene.add( light );
                var light = new THREE.DirectionalLight( 0x002288 );
                light.position.set( - 1, - 1, - 1 );
                scene.add( light );
                var light = new THREE.AmbientLight( 0x222222 );
                scene.add( light );
                //
                window.addEventListener( 'resize', onWindowResize, false );
            }
            function onWindowResize() {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize( window.innerWidth, window.innerHeight );
            }
            function animate() {
                requestAnimationFrame( animate );
                controls.update(); // only required if controls.enableDamping = true, or if controls.autoRotate = true
                render();
            }
            function render() {
                renderer.render( scene, camera );
            }</script>
</body>
</html>

 

The code above works fine and I'm able to control the camera.

 

Do you have any idea why I'm being unable to control camera rotation with babylonjs? How can I debug this to figure out why the camera is not rotating? I'm an experienced C++ developer but very inexperienced in Javascript.

 

Thanks in advance,

Alex

 

 

 

 

Link to comment
Share on other sites

Hello! can you try to remove the pep.js link just in case?

Also we are using pointer events and not mouse events which could be the issue here. (can you also try to use camera.attachControl(canvas, false)?

Link to comment
Share on other sites

Hi, thanks for your answer.

Removed pep.js and used camera.attachControl(canvas,true), didn't work.

Removed pep.js and used camera.attachControl(canvas,false), didn't work.

Added pep.js back with camera.attachControl(canvas,false), didn't work.

I really want to use babylon.js for this (it seems much more evolved than three.js) , so I'm going to learn javascript and start mucking around in the code. If you have any more ideas or if I can do anything to help you figure out what's going on, please feel free to let me know.

Thanks!

Link to comment
Share on other sites

Hi,

I just placed all code in a local folder to make sure it was being loaded. Still doesn't allow me to drag the camera inside Adobe Illustrator.

The code works fine in a browser, it just doesn't work at 100% inside Adobe's chromium container (the events are being captured by the canvas but for some reason the camera isn't rotated when I drag around).

 

Link to comment
Share on other sites

For some reason the pointer events seem to be ignored

 

can you manually add a addEventListener("pointerdown") to see if it is captured?

Also a hack to force using mouse events:

BABYLON.Engine.GetPointerPrefix = function() {

return "mouse"

}

 

Link to comment
Share on other sites

I added your hack to force mouse events before the engine creation line. I also added a pointerdown listener to the canvas. It still doesn't work. Here are two screenshots, the first showing the console while the code is running inside Adobe Illustrator and the second one inside Chrome:

 

Adobe Illustrator

340984415_Screenshot2018-11-01at10_16_29.png.509dd15b7f7207149c471dfc95031aa6.png

 

Chrome:

532154254_Screenshot2018-11-01at10_17_27.thumb.png.eb3f6a4e63bee73dc4d671d9896e2546.png

 

I'm running this in macOS Mojave. Chrome ignores the mouse up/down events. Adobe Illustrator ignores pointer events.

It seems that Adobe's Chromium container doesn't support pointerdown events, but if that's the case, your hack, which I presume merely substitutes the string "pointer" by "mouse", should work.

Update: I placed a console.log inside your BABYLON.Engine.GetPointerPrefix code, and it's not getting called. Did I place your hack in the right place?

 

 

 

Link to comment
Share on other sites

It doesn't get called when dragging. I placed a call in the window resize handler and it's returning what it should, it's just not getting called at all when dragging.

I tested it in Chrome and I'm not seeing any console log messages coming from BABYLON.Engine.GetPointerPrefix as I would expect.

 

<!doctype html>
<!--
/*************************************************************************
* ADOBE CONFIDENTIAL
* ___________________
*
* Copyright 2014 Adobe
* All Rights Reserved.
*
* NOTICE: Adobe permits you to use, modify, and distribute this file in
* accordance with the terms of the Adobe license agreement accompanying
* it. If you have received this file from a source other than Adobe,
* then your use, modification, or distribution of it requires the prior
* written permission of Adobe.
**************************************************************************/
-->
<html>
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/styles.css" />
    <link id="hostStyle" rel="stylesheet" href="css/theme.css" />
    <title></title>

    <style>
        html, body {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #renderCanvas {
            width: 100%;
            height: 100%;
            touch-action: none;
        }
    </style>
    <script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <script src="https://cdn.babylonjs.com/babylon.js"></script>
</head>
<body>
    <canvas id="renderCanvas" touch-action="none"></canvas>
    <script>
var canvas = document.getElementById("renderCanvas"); // Get the canvas element

        var engine = new BABYLON.Engine(canvas, true); // Generate the BABYLON 3D engine

        /******* Add the create scene function ******/
        var createScene = function () {

            // Create the scene space
            var scene = new BABYLON.Scene(engine);

            // Add a camera to the scene and attach it to the canvas
            var camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 2, Math.PI / 2, 2, new BABYLON.Vector3(0,0,5), scene);
            camera.attachControl(canvas, true);

            // Add lights to the scene
            var light1 = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(1, 1, 0), scene);
            var light2 = new BABYLON.PointLight("light2", new BABYLON.Vector3(0, 1, -1), scene);

            // Add and manipulate meshes in the scene
            var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter:6}, scene);

            return scene;
        };
        /******* End of the create scene function ******/

        BABYLON.Engine.GetPointerPrefix = function() {
            console.log("returning mouse.");
            return "mouse";

        }
        var scene = createScene(); //Call the createScene function

        // Register a render loop to repeatedly render the scene
        engine.runRenderLoop(function () {
                scene.render();
        });

        // Watch for browser/canvas resize events
        window.addEventListener("resize", function () {
                engine.resize();

                console.log(BABYLON.Engine.GetPointerPrefix());
        });


        canvas.addEventListener("mouseup", function(){
            console.log("Mouse UP!");
        });

        canvas.addEventListener("mousedown", function(){
            console.log("Mouse DOWN!");
        });

        canvas.addEventListener("pointerdown", function(){
            console.log("pointerdown");
        });

        canvas.addEventListener("click", function(){
            console.log("Mouse Click!");
        });</script>

</body>
</html>

 

Link to comment
Share on other sites

Hey! No need to apologize to me. You're helping me a lot. As for feeling stupid, that comes with the territory. I'm a 43 year old very seasoned developer and I have had (and still have) quite a few shtoopid moments (http://esr.ibiblio.org/?p=8143). 

Good news though, it works in Adobe Illustrator now. When I feel comfortable enough with Javascript (and everything else it involves) I'll try to change babylon.js so that it works in all scenarios without hacks.

Thanks a lot for all your help.

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...