kopia lustrzana https://github.com/OpenDroneMap/WebODM
214 wiersze
7.5 KiB
JavaScript
214 wiersze
7.5 KiB
JavaScript
'use strict';
|
|
var StateGraph = require( 'osg/StateGraph' );
|
|
|
|
var CacheUniformApply = function ( state, program ) {
|
|
this.modelUniform = program._uniformsCache[ state.modelMatrix.getName() ];
|
|
this.viewUniform = program._uniformsCache[ state.viewMatrix.getName() ];
|
|
|
|
this.apply = undefined;
|
|
this.generateUniformsApplyMethods();
|
|
};
|
|
|
|
CacheUniformApply.prototype = {
|
|
|
|
|
|
generateUniformsApplyMethods: function () {
|
|
|
|
var functionStr = [ '//generated by RenderLeaf\n' ];
|
|
functionStr.push( 'var gl = state.getGraphicContext();' );
|
|
functionStr.push( 'var matrixModelViewChanged = state.applyModelViewMatrix( modelview );' );
|
|
functionStr.push( 'state.applyProjectionMatrix( projection );' );
|
|
|
|
if ( this.modelUniform !== undefined ) {
|
|
functionStr.push( 'if ( matrixModelViewChanged ) {' );
|
|
functionStr.push( ' var modelMatrix = state.modelMatrix;' );
|
|
functionStr.push( ' modelMatrix.setMatrix4( model );' );
|
|
functionStr.push( ' modelMatrix.apply( gl, this.modelUniform);' );
|
|
functionStr.push( '};' );
|
|
}
|
|
|
|
if ( this.viewUniform !== undefined ) {
|
|
functionStr.push( 'if ( matrixModelViewChanged ) {' );
|
|
functionStr.push( ' var viewMatrix = state.viewMatrix;' );
|
|
functionStr.push( ' viewMatrix.setMatrix4( view );' );
|
|
functionStr.push( ' viewMatrix.apply( gl, this.viewUniform);' );
|
|
functionStr.push( '};' );
|
|
}
|
|
|
|
// I am the evil, so please bother someone else
|
|
/*jshint evil: true */
|
|
// name the function
|
|
// http://stackoverflow.com/questions/5905492/dynamic-function-name-in-javascript
|
|
var func = ( new Function( 'state', 'modelview', 'model', 'view', 'projection', 'return function RenderLeafApplyMatrixUniformCache( state, modelview, model, view, projection ) { ' + functionStr.join( '\n' ) + '}' ) )();
|
|
/*jshint evil: false */
|
|
|
|
this.apply = func;
|
|
}
|
|
};
|
|
|
|
|
|
var RenderLeaf = function () {
|
|
|
|
this._parent = undefined;
|
|
this._geometry = undefined;
|
|
this._depth = 0.0;
|
|
|
|
this._projection = undefined;
|
|
this._view = undefined;
|
|
this._model = undefined;
|
|
this._modelView = undefined;
|
|
};
|
|
|
|
RenderLeaf.prototype = {
|
|
|
|
reset: function () {
|
|
this._parent = undefined;
|
|
this._geometry = undefined;
|
|
this._depth = 0.0;
|
|
|
|
this._projection = undefined;
|
|
this._view = undefined;
|
|
this._model = undefined;
|
|
this._modelView = undefined;
|
|
},
|
|
|
|
init: function ( parent, geom, projection, view, modelView, model, depth ) {
|
|
|
|
this._parent = parent;
|
|
this._geometry = geom;
|
|
this._depth = depth;
|
|
|
|
this._projection = projection;
|
|
this._view = view;
|
|
this._model = model;
|
|
this._modelView = modelView;
|
|
|
|
},
|
|
|
|
drawGeometry: ( function () {
|
|
|
|
return function ( state ) {
|
|
|
|
|
|
var program = state.getLastProgramApplied();
|
|
var programInstanceID = program.getInstanceID();
|
|
var cache = state.getCacheUniformsApplyRenderLeaf();
|
|
var obj = cache[ programInstanceID ];
|
|
|
|
if ( !obj ) {
|
|
obj = new CacheUniformApply( state, program );
|
|
cache[ programInstanceID ] = obj;
|
|
}
|
|
|
|
obj.apply( state, this._modelView, this._model, this._view, this._projection, this._normal );
|
|
|
|
this._geometry.drawImplementation( state );
|
|
|
|
};
|
|
} )(),
|
|
|
|
render: ( function () {
|
|
var idLastDraw = 0;
|
|
var lastStateSetStackSize = -1;
|
|
|
|
return function ( state, previousLeaf ) {
|
|
|
|
var prevRenderGraph;
|
|
var prevRenderGraphParent;
|
|
var curRenderGraph = this._parent;
|
|
var curRenderGraphParent = curRenderGraph.parent;
|
|
var curRenderGraphStateSet = curRenderGraph.stateset;
|
|
|
|
// When rendering a RenderLeaf we try to limit the state change
|
|
// to do that Graph of State is created during the culling pass.
|
|
// this graph contains nodes of StateGraph type see the class StateGraph
|
|
//
|
|
// So to limit switching of StateSet we check where are the common parent
|
|
// between previous RenderLeaf and this current.
|
|
//
|
|
// There are 3 cases when there is a prev / current render leaf
|
|
//
|
|
//
|
|
// pRG: previousRenderGraph
|
|
// cRG: currentRenderGraph
|
|
// pRL: previousRenderLeaf
|
|
// cRL: currentRenderLeaf
|
|
// each RG contains a StateSet
|
|
//
|
|
// A B C
|
|
// +-----+ +-----+ +-----+ +-----+
|
|
// | pRG | | cRG | +--+ RG +--+ | RG |
|
|
// +--+--+ +--+--+ | +-----+ | +--+--+
|
|
// | | | | |
|
|
// +--v--+ +--v--+ +--v--+ +--v--+ +--v--+
|
|
// | pRG | | cRG | | pRG | | cRG | +--+ RG +--+
|
|
// +--+--+ +--+--+ +--+--+ +--+--+ | +-----+ |
|
|
// | | | | | |
|
|
// +--v--+ +--v--+ +--v--+ +--v--+ +--v--+ +--v--+
|
|
// | pRL | | cRL | | pRL | | cRL | | pRL | | cRL |
|
|
// +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|
|
//
|
|
//
|
|
// Case A
|
|
// no common parent StateGraphNode we need to
|
|
// popStateSet until we find the common parent and then
|
|
// pushStateSet from the common parent to the current
|
|
// RenderLeaf
|
|
//
|
|
// Case B
|
|
// common parent StateGraphNode so we apply the current stateSet
|
|
//
|
|
// Case C
|
|
// the StateGraphNode is common to the previous RenderLeaf so we dont need
|
|
// to do anything except if we used an insertStateSet
|
|
//
|
|
|
|
if ( previousLeaf !== undefined ) {
|
|
|
|
// apply state if required.
|
|
prevRenderGraph = previousLeaf._parent;
|
|
prevRenderGraphParent = prevRenderGraph.parent;
|
|
|
|
if ( prevRenderGraphParent !== curRenderGraphParent ) {
|
|
|
|
// Case A
|
|
StateGraph.moveStateGraph( state, prevRenderGraphParent, curRenderGraphParent );
|
|
|
|
state.applyStateSet( curRenderGraphStateSet );
|
|
|
|
} else if ( curRenderGraph !== prevRenderGraph ) {
|
|
|
|
// Case B
|
|
state.applyStateSet( curRenderGraphStateSet );
|
|
|
|
} else {
|
|
|
|
// Case C
|
|
|
|
// in osg we call apply but actually we dont need
|
|
// except if the stateSetStack changed.
|
|
// for example if insert/remove StateSet has been used
|
|
if ( state._stateSetStackChanged( idLastDraw, lastStateSetStackSize ) ) {
|
|
state.applyStateSet( curRenderGraphStateSet );
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
StateGraph.moveStateGraph( state, undefined, curRenderGraphParent );
|
|
state.applyStateSet( curRenderGraphStateSet );
|
|
|
|
}
|
|
|
|
state._setStateSetsDrawID( ++idLastDraw );
|
|
lastStateSetStackSize = state.getStateSetStackSize();
|
|
|
|
this.drawGeometry( state );
|
|
|
|
};
|
|
} )()
|
|
|
|
};
|
|
|
|
module.exports = RenderLeaf;
|