Преглед на файлове

add light cylinder primitive

tags/2.14.0
Caven Chen преди 3 години
родител
ревизия
d8fd5a8ca3

+ 9
- 0
modules/images/base64/index.js Целия файл

@@ -0,0 +1,9 @@
/**
* @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 Целия файл

@@ -7,6 +7,7 @@

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

+ 17
- 0
modules/material/shader/circle/CircleRingMaterial.glsl Целия файл

@@ -0,0 +1,17 @@
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 Целия файл

@@ -0,0 +1,18 @@
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 Целия файл

@@ -0,0 +1,11 @@
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 Целия файл

@@ -0,0 +1,16 @@
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 Целия файл

@@ -9,6 +9,8 @@ const CircleBlurMaterial = require('../shader/circle/CircleBlurMaterial.glsl')
const CircleDiffuseMaterial = require('../shader/circle/CircleDiffuseMaterial.glsl')
const CircleFadeMaterial = require('../shader/circle/CircleFadeMaterial.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 CircleSpiralMaterial = require('../shader/circle/CircleSpiralMaterial.glsl')
const CircleVaryMaterial = require('../shader/circle/CircleVaryMaterial.glsl')
@@ -90,6 +92,43 @@ Cesium.Material._materialCache.addMaterial(Cesium.Material.CirclePulseType, {
}
})

/**
* 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
* @type {string}

+ 49
- 0
modules/material/type/cylinder.js Целия файл

@@ -0,0 +1,49 @@
/**
* @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 Целия файл

@@ -49,6 +49,7 @@ export { default as DiffuseWallPrimitive } from './primitive/DiffuseWallPrimitiv
export { default as ElecEllipsoidPrimitive } from './primitive/ElecEllipsoidPrimitive'
export { default as FlowLinePrimitive } from './primitive/FlowLinePrimitive'
export { default as LabelPrimitive } from './primitive/LabelPrimitive'
export { default as LightCylinderPrimitive } from './primitive/LightCylinderPrimitive'
export { default as ModelCollectionPrimitive } from './primitive/ModelCollectionPrimitive'
export { default as ModelPrimitive } from './primitive/ModelPrimitive'
export { default as PointPrimitive } from './primitive/PointPrimitive.js'

+ 323
- 0
modules/overlay/primitive/LightCylinderPrimitive.js Целия файл

@@ -0,0 +1,323 @@
/**
* @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 Целия файл

@@ -85,6 +85,7 @@ import {
ElecEllipsoidPrimitive,
FlowLinePrimitive,
LabelPrimitive,
LightCylinderPrimitive,
ModelCollectionPrimitive,
ModelPrimitive,
PointPrimitive,
@@ -299,6 +300,7 @@ const components = {
ElecEllipsoidPrimitive,
FlowLinePrimitive,
LabelPrimitive,
LightCylinderPrimitive,
ModelCollectionPrimitive,
ModelPrimitive,
PointPrimitive,

Loading…
Отказ
Запис