import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import PrimitiveType from "../Core/PrimitiveType.js"; /** * Represents a command to the renderer for drawing. * * @private */ function DrawCommand(options) { options = defaultValue(options, defaultValue.EMPTY_OBJECT); this._boundingVolume = options.boundingVolume; this._orientedBoundingBox = options.orientedBoundingBox; this._cull = defaultValue(options.cull, true); this._occlude = defaultValue(options.occlude, true); this._modelMatrix = options.modelMatrix; this._primitiveType = defaultValue( options.primitiveType, PrimitiveType.TRIANGLES ); this._vertexArray = options.vertexArray; this._count = options.count; this._offset = defaultValue(options.offset, 0); this._instanceCount = defaultValue(options.instanceCount, 0); this._shaderProgram = options.shaderProgram; this._uniformMap = options.uniformMap; this._renderState = options.renderState; this._framebuffer = options.framebuffer; this._pass = options.pass; this._executeInClosestFrustum = defaultValue( options.executeInClosestFrustum, false ); this._owner = options.owner; this._debugShowBoundingVolume = defaultValue( options.debugShowBoundingVolume, false ); this._debugOverlappingFrustums = 0; this._castShadows = defaultValue(options.castShadows, false); this._receiveShadows = defaultValue(options.receiveShadows, false); this._pickId = options.pickId; this._pickOnly = defaultValue(options.pickOnly, false); this._depthForTranslucentClassification = defaultValue( options.depthForTranslucentClassification, false ); this.dirty = true; this.lastDirtyTime = 0; /** * @private */ this.derivedCommands = {}; } Object.defineProperties(DrawCommand.prototype, { /** * The bounding volume of the geometry in world space. This is used for culling and frustum selection. *
* For best rendering performance, use the tightest possible bounding volume. Although
* undefined
is allowed, always try to provide a bounding volume to
* allow the tightest possible near and far planes to be computed for the scene, and
* minimize the number of frustums needed.
*
true
, the renderer frustum and horizon culls the command based on its {@link DrawCommand#boundingVolume}.
* If the command was already culled, set this to false
for a performance improvement.
*
* @memberof DrawCommand.prototype
* @type {Boolean}
* @default true
*/
cull: {
get: function () {
return this._cull;
},
set: function (value) {
if (this._cull !== value) {
this._cull = value;
this.dirty = true;
}
},
},
/**
* When true
, the horizon culls the command based on its {@link DrawCommand#boundingVolume}.
* {@link DrawCommand#cull} must also be true
in order for the command to be culled.
*
* @memberof DrawCommand.prototype
* @type {Boolean}
* @default true
*/
occlude: {
get: function () {
return this._occlude;
},
set: function (value) {
if (this._occlude !== value) {
this._occlude = value;
this.dirty = true;
}
},
},
/**
* The transformation from the geometry in model space to world space.
*
* When undefined
, the geometry is assumed to be defined in world space.
*
false
.
*
* @memberof DrawCommand.prototype
* @type {Boolean}
* @default false
*/
executeInClosestFrustum: {
get: function () {
return this._executeInClosestFrustum;
},
set: function (value) {
if (this._executeInClosestFrustum !== value) {
this._executeInClosestFrustum = value;
this.dirty = true;
}
},
},
/**
* The object who created this command. This is useful for debugging command
* execution; it allows us to see who created a command when we only have a
* reference to the command, and can be used to selectively execute commands
* with {@link Scene#debugCommandFilter}.
*
* @memberof DrawCommand.prototype
* @type {Object}
* @default undefined
*
* @see Scene#debugCommandFilter
*/
owner: {
get: function () {
return this._owner;
},
set: function (value) {
if (this._owner !== value) {
this._owner = value;
this.dirty = true;
}
},
},
/**
* This property is for debugging only; it is not for production use nor is it optimized.
* * Draws the {@link DrawCommand#boundingVolume} for this command, assuming it is a sphere, when the command executes. *
* * @memberof DrawCommand.prototype * @type {Boolean} * @default false * * @see DrawCommand#boundingVolume */ debugShowBoundingVolume: { get: function () { return this._debugShowBoundingVolume; }, set: function (value) { if (this._debugShowBoundingVolume !== value) { this._debugShowBoundingVolume = value; this.dirty = true; } }, }, /** * Used to implement Scene.debugShowFrustums. * @private */ debugOverlappingFrustums: { get: function () { return this._debugOverlappingFrustums; }, set: function (value) { if (this._debugOverlappingFrustums !== value) { this._debugOverlappingFrustums = value; this.dirty = true; } }, }, /** * A GLSL string that will evaluate to a pick id. Whenundefined
, the command will only draw depth
* during the pick pass.
*
* @memberof DrawCommand.prototype
* @type {String}
* @default undefined
*/
pickId: {
get: function () {
return this._pickId;
},
set: function (value) {
if (this._pickId !== value) {
this._pickId = value;
this.dirty = true;
}
},
},
/**
* Whether this command should be executed in the pick pass only.
*
* @memberof DrawCommand.prototype
* @type {Boolean}
* @default false
*/
pickOnly: {
get: function () {
return this._pickOnly;
},
set: function (value) {
if (this._pickOnly !== value) {
this._pickOnly = value;
this.dirty = true;
}
},
},
/**
* Whether this command should be derived to draw depth for classification of translucent primitives.
*
* @memberof DrawCommand.prototype
* @type {Boolean}
* @default false
*/
depthForTranslucentClassification: {
get: function () {
return this._depthForTranslucentClassification;
},
set: function (value) {
if (this._depthForTranslucentClassification !== value) {
this._depthForTranslucentClassification = value;
this.dirty = true;
}
},
},
});
/**
* @private
*/
DrawCommand.shallowClone = function (command, result) {
if (!defined(command)) {
return undefined;
}
if (!defined(result)) {
result = new DrawCommand();
}
result._boundingVolume = command._boundingVolume;
result._orientedBoundingBox = command._orientedBoundingBox;
result._cull = command._cull;
result._occlude = command._occlude;
result._modelMatrix = command._modelMatrix;
result._primitiveType = command._primitiveType;
result._vertexArray = command._vertexArray;
result._count = command._count;
result._offset = command._offset;
result._instanceCount = command._instanceCount;
result._shaderProgram = command._shaderProgram;
result._uniformMap = command._uniformMap;
result._renderState = command._renderState;
result._framebuffer = command._framebuffer;
result._pass = command._pass;
result._executeInClosestFrustum = command._executeInClosestFrustum;
result._owner = command._owner;
result._debugShowBoundingVolume = command._debugShowBoundingVolume;
result._debugOverlappingFrustums = command._debugOverlappingFrustums;
result._castShadows = command._castShadows;
result._receiveShadows = command._receiveShadows;
result._pickId = command._pickId;
result._pickOnly = command._pickOnly;
result._depthForTranslucentClassification =
command._depthForTranslucentClassification;
result.dirty = true;
result.lastDirtyTime = 0;
return result;
};
/**
* Executes the draw command.
*
* @param {Context} context The renderer context in which to draw.
* @param {PassState} [passState] The state for the current render pass.
*/
DrawCommand.prototype.execute = function (context, passState) {
context.draw(this, passState);
};
export default DrawCommand;