Browse Source

add light cylinder primitive

tags/2.14.0
Caven Chen 3 years ago
parent
commit
d8fd5a8ca3

+ 9
- 0
modules/images/base64/index.js View File

/**
* @Author: Caven
* @Date: 2022-05-28 23:30:45
*/

const IMG_PARTICLES =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAEACAYAAADSoXR2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyZpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQ1IDc5LjE2MzQ5OSwgMjAxOC8wOC8xMy0xNjo0MDoyMiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjExQTg0NDEyMDEzQjExRUFBNDhBRjhGMUMzOUUyNTU0IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjExQTg0NDEzMDEzQjExRUFBNDhBRjhGMUMzOUUyNTU0Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MTFBODQ0MTAwMTNCMTFFQUE0OEFGOEYxQzM5RTI1NTQiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MTFBODQ0MTEwMTNCMTFFQUE0OEFGOEYxQzM5RTI1NTQiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz41vRwAAAAE90lEQVR42uydyW4UMRCG3T2dgYSAEGs4sp44cCJBcGUJbwCvALwWPAI8ABwAiUVwgLBdkEikJEiAGMhkZqhfU1aa1sy0g+yaJPyWSupOpPjz0uVyucrJer2eG2fJ3ZgLAQhAgC0PgN8XIlkqgGLE75oih0WmRVZEvop0rHog18rnRe6IzInsthyCXFt+TuSKyGmRXZZDgK5eFrkv8l7kiUhrxN/JSo3pigSvcNmI1bCh3b5LK2+NqHyvyEF9x3z5HgqRRViOAXhW5JrCoNdei/y20gMYxhmRSyIXRY6JTMT4DENLW+SdyD19x/NajDmwmYIW79Hnn+MA4GJEAAIQgABJbMJB+n5Sl9zWZvR9DABUfkJkVt8fi3zUldAEoKl24Y2S1fPZEmBdZFHkkb4vxTLRQ5djbyUf0ncYrD/UADUB8MZno2Q19yx7gIqIAAQgAAEIQIAtYZT+85LvRnjQCoPKR3rQUgN4Y3ZeK30g8qps0qeeAzDn4TWD9+ySG+BBS90DaGnVg9a2tgnR4il9/jkOACoiAhCAAASIZpAAFl6yulO0JACo/IDrn6CedP1zxOciv6wAYNnAP3RVBeWtJQCWzG8iL/X9g4vkqNzMctzUXtintt2KM/aS+bmQaY90rb8CF6tSKiICEIAABCAAAQiwbfcFIWVCbUcc9bZDLKiYAKj4uOv7Bb+ILLj+8W7PCgC7Jhzv44Qdh9yrru8V61jPgd645gD2io+15RiC5ZA5ENNPmGmDmtrta9YAVEQE2FlrQUM/J6efU8cSAD87ojodBaccS6kgiiErGiq/qe93XT+3oGU5BJnbyKrIUs6BQZoQUEcrQ7CYagiGqeKiMgnXLXsg5uJUm/RQJKy8fGS7PMw6SgVQPrJFGZr0kCfUL/7IFjIzrLGpemBQ0kPbehL6I9vMjUh6oEVEAAIQgAAEIAABdpyj0qcK71YrqGUJANNrv+sHOcAiRpDDM1cTY1BEHk7kqyP/2Ac5vLEEQEG8aDnIoTb5ObZRWg5ywG5o1dX4ClNYxT7IISgJPsXGpLut9MCWU0S5bqkmdAa3LQEwcZDAfkZ3tthQfkwNkVeeD6kiuaUabcp6DpS9YyalrAdQ8bT1EFQVUabarND9fNuyB2gREYAABCAAAQhAAAIQoM770UgBXARCIr/koDogVlzgrWuxemBKd0m4JnBed0+5ZQ9gn3BK5LK+P4y5ewoB8DFiKO91COLFfwVuTCZV1hSoYw1APZCsFIkbN1Haaa87wwiKQe6eT27AEX6esPVVd8/kOOdAz/oz9FE0p+uGIKUeqE5C8xgSKiICEIAABCAAAQhAAAIQgAAEIAABCECA6AA+sbkREyDUUYlKD6ggZwzRkr8tewBhusisv+0in5qE/hFchoZTE0TL4p8sTbtIpyahQ4Ag5fKpSVBmfdDECvQTZjoM0U9N6KgkwH9xY7PXpPiCmq5yuaLVldHIO7jgNi5XfOEhCqNh9udHV/RnC5YAUDTftdV4/ivvwEoRVS9XXPWa1FIT5ird8jpSB+BDN3rO8AaGMnGy0I0QRYTvdk6NkOsucuhGCMAgI8Q0isaHbmAevNMhiD4P6iZhstANGiQE2PEGCRo2NcgAsQDwKnxWFdlT17/duWU1BJmuHz6A5bwbEsCScgh+qAHit3Jr1oooOPExdRBLbeJjSpuwuy30AAH+CDAAPH5ltESNYl4AAAAASUVORK5CYII='

export { IMG_PARTICLES }

+ 1
- 0
modules/material/index.js View File



export * from './type/thirdpart' export * from './type/thirdpart'
export * from './type/circle' export * from './type/circle'
export * from './type/cylinder'
export * from './type/ellipsoid' export * from './type/ellipsoid'
export * from './type/polyline' export * from './type/polyline'
export * from './type/radar' export * from './type/radar'

+ 17
- 0
modules/material/shader/circle/CircleRingMaterial.glsl View File

uniform vec4 color;
czm_material czm_getMaterial(czm_materialInput materialInput){
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
vec2 center = st - vec2(0.5,0.5);
float length = length(center) / 0.5;
float time = 1. - abs(czm_frameNumber / 360. - 0.5);
float param = 1. - step(length, 0.6); //大于0.6模糊,rate = 0.6
float scale = param * length; // 0.6< length 返回0,反之返回1.
float alpha = param * (1.0 - abs(scale - 0.8) / 0.2); // 0.8 < length 返回0,反之返回1.
float param1 = step(length, 0.7); //小于0.5模糊
float scale1 = param1 * length; // 0.6< length 返回0,反之返回1.
alpha += param1 * (1.0 - abs(scale1 - 0.35) / 0.35); // 0.8 < length 返回0,反之返回1.
material.diffuse = color.rgb * vec3(color.a);
material.alpha = pow(alpha, 4.0);
return material;
}

+ 18
- 0
modules/material/shader/circle/CircleRotateMaterial.glsl View File

uniform vec4 color;
uniform sampler2D image;
czm_material czm_getMaterial(czm_materialInput materialInput){
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
vec2 center = st - vec2(0.5,0.5);
float time = -czm_frameNumber * 3.1415926 / 180.;
float sin_t = sin(time);
float cos_t = cos(time);
vec2 center_rotate = vec2(center.s * cos_t - center.t * sin_t + 0.5,center.s * sin_t + center.t * cos_t + 0.5);
vec4 colorImage = texture2D(image,center_rotate);
vec3 temp = colorImage.rgb * color.rgb;
temp *= color.a;
material.diffuse = temp;
float length = 2. - length(center) / 0.5;
material.alpha = colorImage.a * pow(length, 0.5);
return material;
}

+ 11
- 0
modules/material/shader/cylinder/CylinderFadeMaterial.glsl View File

uniform vec4 color;
czm_material czm_getMaterial(czm_materialInput materialInput){
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
float powerRatio = 1. / (fract(czm_frameNumber / 30.0) + 1.) ;
float alpha = pow(1. - st.t,powerRatio);
vec4 temp = vec4(color.rgb, alpha * color.a);
material.diffuse = temp.rgb;
material.alpha = temp.a;
return material;
}

+ 16
- 0
modules/material/shader/cylinder/CylinderParticlesMaterial.glsl View File

uniform vec4 color;
uniform sampler2D image;
czm_material czm_getMaterial(czm_materialInput materialInput){
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
float time = fract(czm_frameNumber / 90.) ;
vec2 new_st = fract(st- vec2(time,time));
vec4 colorImage = texture2D(image, new_st);
vec3 diffuse = colorImage.rgb;
float alpha = colorImage.a;
diffuse *= color.rgb;
alpha *= color.a;
material.diffuse = diffuse;
material.alpha = alpha * pow(1. - st.t,color.a);
return material;
}

+ 39
- 0
modules/material/type/circle.js View File

const CircleDiffuseMaterial = require('../shader/circle/CircleDiffuseMaterial.glsl') const CircleDiffuseMaterial = require('../shader/circle/CircleDiffuseMaterial.glsl')
const CircleFadeMaterial = require('../shader/circle/CircleFadeMaterial.glsl') const CircleFadeMaterial = require('../shader/circle/CircleFadeMaterial.glsl')
const CirclePulseMaterial = require('../shader/circle/CirclePulseMaterial.glsl') const CirclePulseMaterial = require('../shader/circle/CirclePulseMaterial.glsl')
const CircleRingMaterial = require('../shader/circle/CircleRingMaterial.glsl')
const CircleRotateMaterial = require('../shader/circle/CircleRotateMaterial.glsl')
const CircleScanMaterial = require('../shader/circle/CircleScanMaterial.glsl') const CircleScanMaterial = require('../shader/circle/CircleScanMaterial.glsl')
const CircleSpiralMaterial = require('../shader/circle/CircleSpiralMaterial.glsl') const CircleSpiralMaterial = require('../shader/circle/CircleSpiralMaterial.glsl')
const CircleVaryMaterial = require('../shader/circle/CircleVaryMaterial.glsl') const CircleVaryMaterial = require('../shader/circle/CircleVaryMaterial.glsl')
} }
}) })


/**
* CircleRing
* @type {string}
*/
Cesium.Material.CircleRingType = 'CircleRing'
Cesium.Material._materialCache.addMaterial(Cesium.Material.CircleRingType, {
fabric: {
type: Cesium.Material.CircleRingType,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 0.7)
},
source: CircleRingMaterial
},
translucent: function(material) {
return true
}
})

/**
* CircleRotate
* @type {string}
*/
Cesium.Material.CircleRotateType = 'CircleRotate'
Cesium.Material._materialCache.addMaterial(Cesium.Material.CircleRotateType, {
fabric: {
type: Cesium.Material.CircleRotateType,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),
image: Cesium.Material.DefaultImageId
},
source: CircleRotateMaterial
},
translucent: function(material) {
return true
}
})

/** /**
* CircleScan * CircleScan
* @type {string} * @type {string}

+ 49
- 0
modules/material/type/cylinder.js View File

/**
* @Author: Caven
* @Date: 2022-05-28 21:36:23
*/

import { Cesium } from '@dc-modules/namespace'

const CylinderFadeMaterial = require('../shader/cylinder/CylinderFadeMaterial.glsl')
const CylinderParticlesMaterial = require('../shader/cylinder/CylinderParticlesMaterial.glsl')

/**
* CylinderFade
* @type {string}
*/
Cesium.Material.CylinderFadeType = 'CylinderFade'
Cesium.Material._materialCache.addMaterial(Cesium.Material.CylinderFadeType, {
fabric: {
type: Cesium.Material.CylinderFadeType,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 0.7)
},
source: CylinderFadeMaterial
},
translucent: function(material) {
return true
}
})

/**
* CylinderParticles
* @type {string}
*/
Cesium.Material.CylinderParticlesType = 'CylinderParticles'
Cesium.Material._materialCache.addMaterial(
Cesium.Material.CylinderParticlesType,
{
fabric: {
type: Cesium.Material.CylinderParticlesType,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 0.7),
image: Cesium.Material.DefaultImageId
},
source: CylinderParticlesMaterial
},
translucent: function(material) {
return true
}
}
)

+ 1
- 0
modules/overlay/index.js View File

export { default as ElecEllipsoidPrimitive } from './primitive/ElecEllipsoidPrimitive' export { default as ElecEllipsoidPrimitive } from './primitive/ElecEllipsoidPrimitive'
export { default as FlowLinePrimitive } from './primitive/FlowLinePrimitive' export { default as FlowLinePrimitive } from './primitive/FlowLinePrimitive'
export { default as LabelPrimitive } from './primitive/LabelPrimitive' export { default as LabelPrimitive } from './primitive/LabelPrimitive'
export { default as LightCylinderPrimitive } from './primitive/LightCylinderPrimitive'
export { default as ModelCollectionPrimitive } from './primitive/ModelCollectionPrimitive' export { default as ModelCollectionPrimitive } from './primitive/ModelCollectionPrimitive'
export { default as ModelPrimitive } from './primitive/ModelPrimitive' export { default as ModelPrimitive } from './primitive/ModelPrimitive'
export { default as PointPrimitive } from './primitive/PointPrimitive.js' export { default as PointPrimitive } from './primitive/PointPrimitive.js'

+ 323
- 0
modules/overlay/primitive/LightCylinderPrimitive.js View File

/**
* @Author: Caven
* @Date: 2022-05-28 10:25:24
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import Parse from '@dc-modules/parse/Parse'
import { Util } from '@dc-modules/utils'
import { Transform } from '@dc-modules/transform'
import { IMG_PARTICLES } from '@dc-modules/images/base64'
import Overlay from '../Overlay'

const DEF_STYLE = {
color: Cesium.Color.ORANGE
}

class LightCylinderPrimitive extends Overlay {
constructor(center, length, topRadius, bottomRadius) {
super()
this._center = Parse.parsePosition(center)
this._length = length || 100
this._topRadius = topRadius || 1
this._bottomRadius = bottomRadius || 50
this._delegate = new Cesium.PrimitiveCollection()
this._style = { ...DEF_STYLE }
this._state = State.INITIALIZED
}

get type() {
return Overlay.getOverlayType('light-cylinder-primitive')
}

set center(position) {
this._center = Parse.parsePosition(position)
this._updatePrimitives()
return this
}

get center() {
return this._center
}

set length(length) {
this._length = length
this._updatePrimitives()
return this
}

get length() {
return this._length
}

set topRadius(topRadius) {
this._topRadius = topRadius
this._updatePrimitives()
return this
}

get topRadius() {
return this._topRadius
}

set bottomRadius(bottomRadius) {
this._bottomRadius = bottomRadius
this._updatePrimitives()
return this
}

get bottomRadius() {
return this._bottomRadius
}

/**
*
* @param center
* @param radius
* @return {[]}
* @private
*/
_computeEllipsePositions(center, radius) {
let cep = Cesium.EllipseGeometryLibrary.computeEllipsePositions(
{
center: Transform.transformWGS84ToCartesian(center),
semiMajorAxis: radius,
semiMinorAxis: radius,
rotation: 0,
granularity: 0.005
},
false,
true
)
let pnts = Cesium.Cartesian3.unpackArray(cep.outerPositions)
pnts.push(pnts[0])
return pnts
}

/**
*
* @param topPts
* @param bottomPts
* @param height
* @return {Cesium.GeometryInstance}
*/
_createCylinderInstance(topPts, bottomPts, height) {
let newpts = bottomPts.slice()
let length = bottomPts.length
let len_2 = 2 * length
let sts = []
let st_interval = 1.0 / (length - 1)
let define_indices = []
let ep = []
const addHeight = (p, alt = 0) => {
let c = Cesium.Cartographic.fromCartesian(p)
c.height += alt
return Cesium.Cartographic.toCartesian(c)
}
for (let i = 0; i < length; i++) {
ep.push(addHeight(topPts[i], height))
sts.push(i * st_interval, 0)
let i_1 = i + 1
let i_11 = (i + 1) % length
let len_2_i_1 = len_2 - i_1
define_indices.push(...[len_2_i_1 - 1, len_2_i_1, i])
define_indices.push(...[i, i_11, len_2_i_1 - 1])
}

for (let i in ep) {
newpts.push(ep[length - i - 1])
sts.push(1 - i * st_interval, 1)
}

let polygon = Cesium.PolygonGeometry.createGeometry(
new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(newpts),
perPositionHeight: true
})
)
polygon.indices = define_indices
polygon.attributes.st.values = sts
return new Cesium.GeometryInstance({
geometry: polygon
})
}

/**
*
* @return {HTMLCanvasElement}
* @private
*/
_getCircleImage() {
let canvas = document.createElement('canvas')
canvas.width = 512
canvas.height = 512
let ctx = canvas.getContext('2d')
ctx.fillStyle = 'rgba(255,255,255,0)'
ctx.strokeStyle = 'rgba(255, 255, 255,255)'
ctx.setLineDash([50, 50])
ctx.lineWidth = 30
ctx.beginPath()
ctx.arc(256, 256, 150, 0, Math.PI * 2, true)
ctx.stroke()
ctx.restore()
return canvas
}

/**
*
* @param image
* @return {HTMLCanvasElement}
* @private
*/
_getParticlesImage(image) {
let canvas = document.createElement('canvas')
canvas.width = 64
canvas.height = 256
let ctx = canvas.getContext('2d')
ctx.clearRect(0, 0, 64, 256)
ctx.drawImage(image, 0, 0)
ctx.drawImage(image, 33, 0)
return canvas
}

/**
*
* @private
*/
_updatePrimitives() {
this._delegate.removeAll()

const isGroud = this._center.alt === 0

let topPositions = this._computeEllipsePositions(
this._center,
this._topRadius
)
let innerBottomPostions = this._computeEllipsePositions(
this._center,
this._bottomRadius * 0.7
)
let bottomPositions = this._computeEllipsePositions(
this._center,
this._bottomRadius
)

// update buttom circle
const circleOpt = {
geometryInstances: new Cesium.GeometryInstance({
geometry: new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(
this._computeEllipsePositions(this._center, this._bottomRadius * 2)
),
perPositionHeight: !isGroud
})
}),
asynchronous: false
}

// ring
let ring = isGroud
? new Cesium.GroundPrimitive(circleOpt)
: new Cesium.Primitive(circleOpt)

ring.appearance = new Cesium.EllipsoidSurfaceAppearance({
material: Cesium.Material.fromType(Cesium.Material.CircleRingType, {
color: this._style.color
})
})

// circle
let circle = isGroud
? new Cesium.GroundPrimitive(circleOpt)
: new Cesium.Primitive(circleOpt)

circle.appearance = new Cesium.EllipsoidSurfaceAppearance({
material: Cesium.Material.fromType(Cesium.Material.CircleRotateType, {
color: this._style.color,
image: this._getCircleImage()
})
})

// cylinder
let cylinder = new Cesium.Primitive({
geometryInstances: this._createCylinderInstance(
topPositions,
innerBottomPostions,
this._length
),
appearance: new Cesium.EllipsoidSurfaceAppearance({
material: Cesium.Material.fromType(Cesium.Material.CylinderFadeType, {
color: this._style.color
})
}),
asynchronous: false
})

this._delegate.add(ring)
this._delegate.add(circle)
this._delegate.add(cylinder)

// particles
Cesium.Resource.fetchImage({ url: IMG_PARTICLES }).then(image => {
let particles = new Cesium.Primitive({
geometryInstances: this._createCylinderInstance(
topPositions,
bottomPositions,
this._length
),
appearance: new Cesium.EllipsoidSurfaceAppearance({
material: Cesium.Material.fromType(
Cesium.Material.CylinderParticlesType,
{
color: this._style.color,
image: this._getParticlesImage(image)
}
)
}),
asynchronous: false
})
this._delegate.add(particles)
})
}

/**
*
* @private
*/
_mountedHook() {
/**
* set the positions
*/
this.center = this._center
}

/**
*
* @param frameState
*/
update(frameState) {
this._delegate.update(frameState)
}

/**
*
* @param style
* @returns {LightCylinderPrimitive}
*/
setStyle(style) {
if (!style || Object.keys(style).length === 0) {
return this
}
Util.merge(this._style, style)
return this
}

destroy() {
return Cesium.destroyObject(this)
}
}

Overlay.registerType('light-cylinder-primitive')

export default LightCylinderPrimitive

+ 2
- 0
packages/core/src/components.js View File

ElecEllipsoidPrimitive, ElecEllipsoidPrimitive,
FlowLinePrimitive, FlowLinePrimitive,
LabelPrimitive, LabelPrimitive,
LightCylinderPrimitive,
ModelCollectionPrimitive, ModelCollectionPrimitive,
ModelPrimitive, ModelPrimitive,
PointPrimitive, PointPrimitive,
ElecEllipsoidPrimitive, ElecEllipsoidPrimitive,
FlowLinePrimitive, FlowLinePrimitive,
LabelPrimitive, LabelPrimitive,
LightCylinderPrimitive,
ModelCollectionPrimitive, ModelCollectionPrimitive,
ModelPrimitive, ModelPrimitive,
PointPrimitive, PointPrimitive,

Loading…
Cancel
Save