import BoundingRectangle from "../Core/BoundingRectangle.js"; import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Cartesian4 from "../Core/Cartesian4.js"; import Color from "../Core/Color.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import DeveloperError from "../Core/DeveloperError.js"; import DistanceDisplayCondition from "../Core/DistanceDisplayCondition.js"; import Matrix4 from "../Core/Matrix4.js"; import NearFarScalar from "../Core/NearFarScalar.js"; import SceneMode from "./SceneMode.js"; import SceneTransforms from "./SceneTransforms.js"; /** *
value
's red
, green
,
* blue
, and alpha
properties as shown in Example 1. These components range from 0.0
* (no intensity) to 1.0
(full intensity).
* @memberof PointPrimitive.prototype
* @type {Color}
*
* @example
* // Example 1. Assign yellow.
* p.color = Cesium.Color.YELLOW;
*
* @example
* // Example 2. Make a pointPrimitive 50% translucent.
* p.color = new Cesium.Color(1.0, 1.0, 1.0, 0.5);
*/
color: {
get: function () {
return this._color;
},
set: function (value) {
//>>includeStart('debug', pragmas.debug);
if (!defined(value)) {
throw new DeveloperError("value is required.");
}
//>>includeEnd('debug');
const color = this._color;
if (!Color.equals(color, value)) {
Color.clone(value, color);
makeDirty(this, COLOR_INDEX);
}
},
},
/**
* Gets or sets the outline color of the point.
* @memberof PointPrimitive.prototype
* @type {Color}
*/
outlineColor: {
get: function () {
return this._outlineColor;
},
set: function (value) {
//>>includeStart('debug', pragmas.debug);
if (!defined(value)) {
throw new DeveloperError("value is required.");
}
//>>includeEnd('debug');
const outlineColor = this._outlineColor;
if (!Color.equals(outlineColor, value)) {
Color.clone(value, outlineColor);
makeDirty(this, OUTLINE_COLOR_INDEX);
}
},
},
/**
* Gets or sets the outline width in pixels. This width adds to pixelSize,
* increasing the total size of the point.
* @memberof PointPrimitive.prototype
* @type {number}
*/
outlineWidth: {
get: function () {
return this._outlineWidth;
},
set: function (value) {
//>>includeStart('debug', pragmas.debug);
if (!defined(value)) {
throw new DeveloperError("value is required.");
}
//>>includeEnd('debug');
if (this._outlineWidth !== value) {
this._outlineWidth = value;
makeDirty(this, OUTLINE_WIDTH_INDEX);
}
},
},
/**
* Gets or sets the condition specifying at what distance from the camera that this point will be displayed.
* @memberof PointPrimitive.prototype
* @type {DistanceDisplayCondition}
* @default undefined
*/
distanceDisplayCondition: {
get: function () {
return this._distanceDisplayCondition;
},
set: function (value) {
//>>includeStart('debug', pragmas.debug);
if (defined(value) && value.far <= value.near) {
throw new DeveloperError("far must be greater than near");
}
//>>includeEnd('debug');
if (
!DistanceDisplayCondition.equals(this._distanceDisplayCondition, value)
) {
this._distanceDisplayCondition = DistanceDisplayCondition.clone(
value,
this._distanceDisplayCondition
);
makeDirty(this, DISTANCE_DISPLAY_CONDITION_INDEX);
}
},
},
/**
* Gets or sets the distance from the camera at which to disable the depth test to, for example, prevent clipping against terrain.
* When set to zero, the depth test is always applied. When set to Number.POSITIVE_INFINITY, the depth test is never applied.
* @memberof PointPrimitive.prototype
* @type {number}
* @default 0.0
*/
disableDepthTestDistance: {
get: function () {
return this._disableDepthTestDistance;
},
set: function (value) {
if (this._disableDepthTestDistance !== value) {
//>>includeStart('debug', pragmas.debug);
if (!defined(value) || value < 0.0) {
throw new DeveloperError(
"disableDepthTestDistance must be greater than or equal to 0.0."
);
}
//>>includeEnd('debug');
this._disableDepthTestDistance = value;
makeDirty(this, DISABLE_DEPTH_DISTANCE_INDEX);
}
},
},
/**
* Gets or sets the user-defined value returned when the point is picked.
* @memberof PointPrimitive.prototype
* @type {*}
*/
id: {
get: function () {
return this._id;
},
set: function (value) {
this._id = value;
if (defined(this._pickId)) {
this._pickId.object.id = value;
}
},
},
/**
* @private
*/
pickId: {
get: function () {
return this._pickId;
},
},
/**
* Determines whether or not this point will be shown or hidden because it was clustered.
* @memberof PointPrimitive.prototype
* @type {boolean}
* @private
*/
clusterShow: {
get: function () {
return this._clusterShow;
},
set: function (value) {
if (this._clusterShow !== value) {
this._clusterShow = value;
makeDirty(this, SHOW_INDEX);
}
},
},
});
PointPrimitive.prototype.getPickId = function (context) {
if (!defined(this._pickId)) {
this._pickId = context.createPickId({
primitive: this,
collection: this._collection,
id: this._id,
});
}
return this._pickId;
};
PointPrimitive.prototype._getActualPosition = function () {
return this._actualPosition;
};
PointPrimitive.prototype._setActualPosition = function (value) {
Cartesian3.clone(value, this._actualPosition);
makeDirty(this, POSITION_INDEX);
};
const tempCartesian3 = new Cartesian4();
PointPrimitive._computeActualPosition = function (
position,
frameState,
modelMatrix
) {
if (frameState.mode === SceneMode.SCENE3D) {
return position;
}
Matrix4.multiplyByPoint(modelMatrix, position, tempCartesian3);
return SceneTransforms.computeActualWgs84Position(frameState, tempCartesian3);
};
const scratchCartesian4 = new Cartesian4();
// This function is basically a stripped-down JavaScript version of PointPrimitiveCollectionVS.glsl
PointPrimitive._computeScreenSpacePosition = function (
modelMatrix,
position,
scene,
result
) {
// Model to world coordinates
const positionWorld = Matrix4.multiplyByVector(
modelMatrix,
Cartesian4.fromElements(
position.x,
position.y,
position.z,
1,
scratchCartesian4
),
scratchCartesian4
);
const positionWC = SceneTransforms.wgs84ToWindowCoordinates(
scene,
positionWorld,
result
);
return positionWC;
};
/**
* Computes the screen-space position of the point's origin.
* The screen space origin is the top, left corner of the canvas; x
increases from
* left to right, and y
increases from top to bottom.
*
* @param {Scene} scene The scene.
* @param {Cartesian2} [result] The object onto which to store the result.
* @returns {Cartesian2} The screen-space position of the point.
*
* @exception {DeveloperError} PointPrimitive must be in a collection.
*
* @example
* console.log(p.computeScreenSpacePosition(scene).toString());
*/
PointPrimitive.prototype.computeScreenSpacePosition = function (scene, result) {
const pointPrimitiveCollection = this._pointPrimitiveCollection;
if (!defined(result)) {
result = new Cartesian2();
}
//>>includeStart('debug', pragmas.debug);
if (!defined(pointPrimitiveCollection)) {
throw new DeveloperError("PointPrimitive must be in a collection.");
}
if (!defined(scene)) {
throw new DeveloperError("scene is required.");
}
//>>includeEnd('debug');
const modelMatrix = pointPrimitiveCollection.modelMatrix;
const windowCoordinates = PointPrimitive._computeScreenSpacePosition(
modelMatrix,
this._actualPosition,
scene,
result
);
if (!defined(windowCoordinates)) {
return undefined;
}
windowCoordinates.y = scene.canvas.clientHeight - windowCoordinates.y;
return windowCoordinates;
};
/**
* Gets a point's screen space bounding box centered around screenSpacePosition.
* @param {PointPrimitive} point The point to get the screen space bounding box for.
* @param {Cartesian2} screenSpacePosition The screen space center of the label.
* @param {BoundingRectangle} [result] The object onto which to store the result.
* @returns {BoundingRectangle} The screen space bounding box.
*
* @private
*/
PointPrimitive.getScreenSpaceBoundingBox = function (
point,
screenSpacePosition,
result
) {
const size = point.pixelSize;
const halfSize = size * 0.5;
const x = screenSpacePosition.x - halfSize;
const y = screenSpacePosition.y - halfSize;
const width = size;
const height = size;
if (!defined(result)) {
result = new BoundingRectangle();
}
result.x = x;
result.y = y;
result.width = width;
result.height = height;
return result;
};
/**
* Determines if this point equals another point. Points are equal if all their properties
* are equal. Points in different collections can be equal.
*
* @param {PointPrimitive} other The point to compare for equality.
* @returns {boolean} true
if the points are equal; otherwise, false
.
*/
PointPrimitive.prototype.equals = function (other) {
return (
this === other ||
(defined(other) &&
this._id === other._id &&
Cartesian3.equals(this._position, other._position) &&
Color.equals(this._color, other._color) &&
this._pixelSize === other._pixelSize &&
this._outlineWidth === other._outlineWidth &&
this._show === other._show &&
Color.equals(this._outlineColor, other._outlineColor) &&
NearFarScalar.equals(this._scaleByDistance, other._scaleByDistance) &&
NearFarScalar.equals(
this._translucencyByDistance,
other._translucencyByDistance
) &&
DistanceDisplayCondition.equals(
this._distanceDisplayCondition,
other._distanceDisplayCondition
) &&
this._disableDepthTestDistance === other._disableDepthTestDistance)
);
};
PointPrimitive.prototype._destroy = function () {
this._pickId = this._pickId && this._pickId.destroy();
this._pointPrimitiveCollection = undefined;
};
export default PointPrimitive;