#147 ✓resolved
lindsay.kay (at xeolabs)

Add events to BoundingBox node

Reported by lindsay.kay (at xeolabs) | August 12th, 2010 @ 05:50 AM | in V0.7.7

Have the SceneJS.BoundingBox declare its various states of locality and view frustum intersection with events. Make it also declare each level-of-detail (LOD) switch through events.

How BoundingBox Nodes Work

When rendered, a BoundingBox tests itself for intersection with the scene's inner and outer "locality spheres", which are a pair of radii centered at the viewer's eye position. These are defined either explicitly by a higher SceneJS.Locality node, or implicitly as defaults of 10000 and 20000 for inner and outer radii, respectively.

If that intersection test passes, then the BoundingBox tests itself for intersection with the view frustum defined by the higher SceneJS.Camera node. If that passes, it then proceeds to render a subgraph.

If a BoundingBox has a LOD "levels" array property, which specifies an ascendingly-order list of thresholds for the BoundingBox projected Canvas size, then it selects the level corresponding to the threshold immediately below its current projected size. At this point, if it has child nodes, it renders the child corresponding to the level index.

If the BoundingBox has only one child, it renders that one regardless of the selected level.

Events to Fire

A BoundingBox is to fire a "state-changed" event whenever the intersection status of the BoundingBox changes, and a "lod-selected" event whenever a new LOD level is selected within the current intersection state.

Listeners on the BoundingBox look like so:


SceneJS.boundingBox({
    xmin: -20,
    ymin: -20,
    zmin: -20,
    xmax:  20,
    ymax:  20,
    zmax:  20,

    /* LOD levels 
     */
    levels: [
        10,     // Level 1
        200,    // Level 2
        400,    // Level 3
        500,    // Level 4
        600     // Level 5
    ],

    /** Events
     *
     */
    listeners: {

        "state-changed" : function(params) {
            switch (params.newState) {

                /**
                 * State of the BoundingBox when it is completely outside
                 * the outer locality radius, which which may be either
                 * that defined explicitly by a higher SceneJS.Locality
                 * node, or the default radius value (see SceneJS.Locality).
                 * In this state it is therefore also completely outside
                 * the inner radius and the view frustum.
                 */
                case SceneJS.BoundingBox.STATE_OUTSIDE_OUTER_LOCALITY:
                    alert("SceneJS.BoundingBox.STATE_OUTSIDE_OUTER_LOCALITY");
                    break;

                /* State of the BoundingBox when it intersects the outer
                 * locality radius, but does not intersect the inner radius
                 */
                case SceneJS.BoundingBox.STATE_INTERSECTING_OUTER_LOCALITY:
                    alert("SceneJS.BoundingBox.STATE_INTERSECTING_OUTER_LOCALITY");
                    break;

                /* State of the BoundingBox when it intersects the inner
                 * locality radius, while therefore also intersecting the
                 * outer locality radius
                 */
                case SceneJS.BoundingBox.STATE_INTERSECTING_INNER_LOCALITY:
                    alert("SceneJS.BoundingBox.STATE_INTERSECTING_INNER_LOCALITY");
                    break;

                /* State of the BoundingBox when it is intersecting the
                 * view frustum, while therefore also intersecting
                 * the inner and outer locality radius
                 */
                case SceneJS.BoundingBox.STATE_INTERSECTING_FRUSTUM:
                    alert("SceneJS.BoundingBox.STATE_INTERSECTING_FRUSTUM");
                    break;
            }
        },

        "lod-selected" : function(event) {

            /**
             * BoundingBox when has selected an initial or
             * new level of detail (LOD) while intersecting the
             * view frustum. When it has a child node for each
             * level, then it will be about to render that
             * particular child. When it has only one child
             * node, then it will render that child regardless
             * of which level it has selected. When it has no
             * children, then it will happily not render
             * any children.
             */

            alert("SceneJS.BoundingBox.STATE_LOD_SELECTED: oldLevel=" +
                  event.params.oldLevel + ", new = " + event.params.newLevel);
        }
    }
},
    // Child node for each LOD

        SceneJS.node(// .. 
                ),

        SceneJS.node(// .. 
                ),

        SceneJS.node(// ..                
                ),

        SceneJS.node(// ..                
                ),

        SceneJS.node(// ..                
                )
        );

Listening to Events with Super Node

We can have the BoundingBox relay its events up the tree. In the example below, it relays them to a parent Node as "gone" when outside the outer locality, "distant" when outside inner radius, "near" when inside inner radius, and "visible" when in viewing frustum. For each change of LOD, it fires "detail-selected".

SceneJS.node({

    listeners: {

        "gone" : function(event) {
            alert("gone");
        },

        "distant" : function(event) {
            alert("distant");
        },

        "near" : function(event) {
            alert("near");
        },

        "visible" : function(event) {
            alert("visible");
        },

        "detail-selected" : function (params) {
            alert("detail-selected: oldLevel = "
                    + params.oldLevel
                    + ", newLevel = " + params.newLevel);
        }
    }
},
        SceneJS.boundingBox({
            xmin: -20,
            ymin: -20,
            zmin: -20,
            xmax:  20,
            ymax:  20,
            zmax:  20,

            /* LOD levels
             */
            levels: [
                10,     // Level 1
                200,    // Level 2
                400,    // Level 3
                500,    // Level 4
                600     // Level 5
            ],

            /** Events
             *
             */
            listeners: {

                "state-changed" : function(params) {
                    switch (params.newState) {

                        /**
                         * State of the BoundingBox when it is completely outside
                         * the outer locality radius, which which may be either
                         * that defined explicitly by a higher SceneJS.Locality
                         * node, or the default radius value (see SceneJS.Locality).
                         * In this state it is therefore also completely outside
                         * the inner radius and the view frustum.
                         */
                        case SceneJS.BoundingBox.STATE_OUTSIDE_OUTER_LOCALITY:
                            this.fireEvent("gone");
                            break;

                        /* State of the BoundingBox when it intersects the outer
                         * locality radius, but does not intersect the inner radius
                         */
                        case SceneJS.BoundingBox.STATE_INTERSECTING_OUTER_LOCALITY:
                            this.fireEvent("distant");
                            break;

                        /* State of the BoundingBox when it intersects the inner
                         * locality radius, while therefore also intersecting the
                         * outer locality radius
                         */
                        case SceneJS.BoundingBox.STATE_INTERSECTING_INNER_LOCALITY:
                            this.fireEvent("near");
                            break;

                        /* State of the BoundingBox when it is intersecting the
                         * view frustum, while therefore also intersecting
                         * the inner and outer locality radius
                         */
                        case SceneJS.BoundingBox.STATE_INTERSECTING_FRUSTUM:
                            this.fireEvent("visible");
                            break;
                    }
                },

                "lod-selected" : function(params) {

                    /**
                     * BoundingBox when has selected an initial or
                     * new level of detail (LOD) while intersecting the
                     * view frustum. When it has a child node for each
                     * level, then it will be about to render that
                     * particular child. When it has only one child
                     * node, then it will render that child regardless
                     * of which level it has selected. When it has no
                     * children, then it will happily not render
                     * any children.
                     */

                     this.fireEvent("detail-selected", params);
                }
            }
        },
            // Child node for each LOD

                SceneJS.node(// ..
                        ),

                SceneJS.node(// ..
                        ),

                SceneJS.node(// ..
                        ),

                SceneJS.node(// ..
                        ),

                SceneJS.node(// ..
                        )
                ));

No comments found

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

SceneJS provides easy access to WebGL through a simple and declarative JavaScript API. The SceneJS API is functional, which enables its scene definitions to be really compact and expressive, while hooking into other JavaScript code just that little bit more smoothly.

Shared Ticket Bins

People watching this ticket

Pages