Skip to content

Commit

Permalink
feat: 更新 zxtool-three-utils
Browse files Browse the repository at this point in the history
  • Loading branch information
stupidZhu committed Jan 21, 2024
1 parent 98d7681 commit 4cb68de
Show file tree
Hide file tree
Showing 44 changed files with 1,547 additions and 776 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { 结合1 } from "./结合"

class CesiumThreeService {
moduleEnter() {
threeHelper.add(new DevPlugin({ axesSize: 1e7 }))
threeHelper.addPlugin(new DevPlugin({ axesSize: 1e7 }))
this.init()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const cartToVec = function (cart: Cesium.Cartesian3) {

export const 结合1 = async () => {
const viewer = ViewerHelper.getViewer()!
threeHelper.add(new SyncCesiumPlugin(viewer))
threeHelper.addPlugin(new SyncCesiumPlugin(viewer))
const scene = threeHelper.getWidget("scene")!

const entity = viewer.entities.add({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js"
export const 发光 = () => {
const scene = threeHelper.getWidget("scene")!
const renderer = threeHelper.getWidget("renderer")!
const camera = threeHelper.getWidget("p_camera")!
const camera = threeHelper.getWidget("camera")!

const geometry = new THREE.SphereGeometry(1, 32, 32)
const material = new THREE.MeshBasicMaterial({ color: "teal" })
Expand Down Expand Up @@ -37,7 +37,9 @@ export const 发光 = () => {
outlinePass.selectedObjects = [sphere, cube, torusKnot]

threeHelper.animationCollection.delete(Symbol.for("update_renderer"))
threeHelper.animationCollection.set("update_renderPass", (_, delta) => {
composer.render(delta)
threeHelper.animationCollection.set("update_renderPass", {
fn: ({ delta }) => {
composer.render(delta)
},
})
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,8 @@ const flag = { current: false }

class ThreePageService {
moduleEnter() {
threeHelper.add(new DevPlugin())
threeHelper.addPlugin(new DevPlugin())
this.init()

// const plugin = new OrbitControlsPlugin()
// setInterval(() => {
// if (flag.current) {
// threeHelper.remove(plugin)
// flag.current = false
// } else {
// threeHelper.add(plugin)
// flag.current = true
// }
// }, 5000)
}

moduleExit() {}
Expand Down
3 changes: 2 additions & 1 deletion packages/tsconfig/base.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"allowSyntheticDefaultImports": true,
"suppressImplicitAnyIndexErrors": true,
"ignoreDeprecations": "5.0",
"jsx": "react-jsx"
"jsx": "react-jsx",
"suppressExcessPropertyErrors": true
},
"exclude": ["node_modules"]
}
1 change: 1 addition & 0 deletions packages/zxtool-cesium-utils/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./materialProperty"
export type * from "./type"
export * from "./util"
export * from "./v2"
export * from "./widget"
41 changes: 41 additions & 0 deletions packages/zxtool-cesium-utils/src/v2/CesiumHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { EmitterHelper, IObj } from "@zxtool/utils"
import { CesiumHelperPlugin, CesiumHelperPluginProps } from "./plugins"
import { ViewerPlugin } from "./plugins/ViewerPlugin"

export class CesiumHelper {
private isInit = false
private readonly emitter = new EmitterHelper({ maxCount: { history: 1 } })
private readonly widgetCollection: Map<PropertyKey, any> = new Map()

readonly pluginCollection: Map<PropertyKey, CesiumHelperPlugin> = new Map()

getWidget(key: PropertyKey): unknown {
return this.widgetCollection.get(key)
}
getWidgetAsync(key: PropertyKey) {
return this.emitter.onceAsync(key, true).promise
}

addPlugin<AO extends IObj>(plugin: CesiumHelperPlugin<AO>, options?: AO) {
const props: CesiumHelperPluginProps = {
emitter: this.emitter,
widgetCollection: this.widgetCollection,
cesiumHelper: this,
}
plugin.add(props, options)
return this
}
removePlugin<RO extends IObj>(plugin: CesiumHelperPlugin<IObj, RO>, options?: RO) {
plugin.remove(options)
return this
}

init(container: string | Element) {
if (this.isInit) return

// todo
this.addPlugin(new ViewerPlugin(), { container })

this.isInit = true
}
}
2 changes: 2 additions & 0 deletions packages/zxtool-cesium-utils/src/v2/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./CesiumHelper"
export * from "./plugins"
67 changes: 67 additions & 0 deletions packages/zxtool-cesium-utils/src/v2/plugins/ViewerPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import * as Cesium from "cesium"
import { CesiumHelperPlugin, CesiumHelperPluginProps } from "."
import { CesiumUtil, ViewerUtilSync } from "../../util"
import { genZCUInfo } from "../../util/util"

export type ViewerPluginAO = Cesium.Viewer.ConstructorOptions & {
container: string | Element
hideWidget?: boolean
fxaa?: boolean
enableIframe?: boolean
}

const genInfo = genZCUInfo("ViewerPlugin")

export class ViewerPlugin implements CesiumHelperPlugin<ViewerPluginAO> {
private key = Symbol.for("viewer")
private addProps: CesiumHelperPluginProps | null = null

private _viewer?: Cesium.Viewer
get viewer() {
return this._viewer
}

add(props: CesiumHelperPluginProps, options: ViewerPluginAO): ViewerPlugin {
this.addProps = props
const { cesiumHelper, widgetCollection, emitter } = props
const { pluginCollection } = cesiumHelper

const plugin = pluginCollection.get(this.key) as ViewerPlugin
if (plugin) {
console.error(genInfo("已经存在一个 ViewerPlugin, 不能重复添加"))
return plugin
}

const { container, hideWidget = true, fxaa = true, enableIframe, ...rest } = options
if (!container) throw new Error("请传入 container")

const viewer = new Cesium.Viewer(container, { ...(hideWidget ? ViewerUtilSync.getHideWidgetOption() : null), ...rest })
// @ts-ignore
if (hideWidget) viewer.cesiumWidget.creditContainer.style.display = "none"
fxaa && ViewerUtilSync.fxaa(viewer)
enableIframe && CesiumUtil.enableIframe()
viewer.scene.globe.depthTestAgainstTerrain = true

this._viewer = viewer
widgetCollection.set("viewer", viewer)
emitter.emit("viewer", viewer)

pluginCollection.set(this.key, this)
return this
}

remove(): void {
if (!this.addProps) throw new Error(genInfo("未添加的插件不能被移除"))
const { cesiumHelper, widgetCollection, emitter } = this.addProps
const { pluginCollection } = cesiumHelper

widgetCollection.delete("viewer")
emitter.clearHistory("viewer")

this.viewer?.destroy()
this._viewer = undefined

pluginCollection.delete(this.key)
this.addProps = null
}
}
14 changes: 14 additions & 0 deletions packages/zxtool-cesium-utils/src/v2/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { EmitterHelper, IObj } from "@zxtool/utils"
import type { CesiumHelper } from "../CesiumHelper"

export interface CesiumHelperPluginProps {
emitter: EmitterHelper
widgetCollection: Map<PropertyKey, any>
cesiumHelper: CesiumHelper
}
export interface CesiumHelperPlugin<AO extends IObj = {}, RO extends IObj = {}> {
add(props: CesiumHelperPluginProps, options?: AO): CesiumHelperPlugin<AO>
remove(options?: RO): void
}

export * from "./ViewerPlugin"
65 changes: 65 additions & 0 deletions packages/zxtool-three-utils/src/geometry/WallGeometry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Num2 } from "@zxtool/utils"
import * as THREE from "three"

export interface WallGeometryProps {
points: Num2[]
height?: number
heights?: Num2[]
uvType?: "PER" | "ALL"
face?: "XOY" | "XOZ"
}

export class WallGeometry extends THREE.BufferGeometry {
type = "WallGeometry"
parameters: WallGeometryProps

constructor(props: WallGeometryProps) {
const { points, height = 1, heights, uvType = "ALL", face = "XOZ" } = props

super()
this.parameters = { points, height, uvType }

const vertices: number[] = []
const uvs: number[] = []
const per = 1 / (points.length - 1)

for (let i = 0; i < points.length - 1; i++) {
const cur = points[i]
const next = points[i + 1]
let curHeight = [0, height]
let nextHeight = [0, height]
if (heights?.[i]) curHeight = [heights[i][0] ?? 0, heights[i][1] ?? height]
if (heights?.[i + 1]) nextHeight = [heights[i + 1][0] ?? 0, heights[i + 1][1] ?? height]

if (face === "XOY") {
vertices.push(cur[0], cur[1], curHeight[0], next[0], next[1], nextHeight[0], next[0], next[1], nextHeight[1])
vertices.push(cur[0], cur[1], curHeight[0], next[0], next[1], nextHeight[1], cur[0], cur[1], curHeight[1])
} else {
vertices.push(cur[0], curHeight[0], cur[1], next[0], nextHeight[0], next[1], next[0], nextHeight[1], next[1])
vertices.push(cur[0], curHeight[0], cur[1], next[0], nextHeight[1], next[1], cur[0], curHeight[1], cur[1])
}

if (uvType === "PER") {
uvs.push(0, 0, 1, 0, 1, 1)
uvs.push(0, 0, 1, 1, 0, 1)
} else {
uvs.push(i * per, 0, (i + 1) * per, 0, (i + 1) * per, 1)
uvs.push(i * per, 0, (i + 1) * per, 1, i * per, 1)
}
}

this.setAttribute("position", new THREE.BufferAttribute(new Float32Array(vertices), 3))
this.setAttribute("uv", new THREE.BufferAttribute(new Float32Array(uvs), 2))
this.computeVertexNormals()
}

copy(source: any) {
super.copy(source)
this.parameters = Object.assign({}, source.parameters)
return this
}

static fromJSON(data: WallGeometryProps) {
return new WallGeometry(data)
}
}
1 change: 1 addition & 0 deletions packages/zxtool-three-utils/src/geometry/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./WallGeometry"
3 changes: 3 additions & 0 deletions packages/zxtool-three-utils/src/helper/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./CustomGridHelper"
export * from "./threeHelper/ThreeHelper"
export * from "./threeHelper/plugins"
67 changes: 67 additions & 0 deletions packages/zxtool-three-utils/src/helper/threeHelper/ThreeHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { EmitterHelper, IObj } from "@zxtool/utils"
import {
AnimationWithState,
FunctionWithState,
StateCbCollection,
ThreeHelperPlugin,
ThreeHelperPluginProps,
} from "./plugins"
import { AnimationPlugin } from "./plugins/AnimationPlugin"
import { PCameraPlugin } from "./plugins/PCameraPlugin"
import { RendererPlugin } from "./plugins/RendererPlugin"
import { ResizePlugin } from "./plugins/ResizePlugin"
import { ScenePlugin } from "./plugins/ScenePlugin"

export interface ThreeHelper {
getWidget(type: "scene"): THREE.Scene | undefined
getWidget(type: "renderer"): THREE.WebGLRenderer | undefined
getWidget(type: "camera"): THREE.Camera | undefined

getWidgetAsync(type: "scene"): Promise<THREE.Scene>
getWidgetAsync(type: "renderer"): Promise<THREE.WebGLRenderer>
getWidgetAsync(type: "camera"): Promise<THREE.Camera>
}

export class ThreeHelper {
private isInit = false
private readonly emitter = new EmitterHelper({ maxCount: { history: 1 } })
private readonly widgetCollection: Map<PropertyKey, any> = new Map()

readonly time = { value: 0 }
readonly animationCollection: StateCbCollection<PropertyKey, AnimationWithState> = new Map()
readonly resizeCollection: StateCbCollection<PropertyKey, FunctionWithState> = new Map()
readonly pluginCollection: Map<PropertyKey, ThreeHelperPlugin> = new Map()

getWidget(key: PropertyKey): unknown {
return this.widgetCollection.get(key)
}
getWidgetAsync(key: PropertyKey) {
return this.emitter.onceAsync(key, true).promise
}

addPlugin<AO extends IObj>(plugin: ThreeHelperPlugin<AO>, options?: AO) {
const props: ThreeHelperPluginProps = {
emitter: this.emitter,
widgetCollection: this.widgetCollection,
threeHelper: this,
}
plugin.add(props, options)
return this
}
removePlugin<RO extends IObj>(plugin: ThreeHelperPlugin<IObj, RO>, options?: RO) {
plugin.remove(options)
return this
}

init(canvas: HTMLCanvasElement) {
if (this.isInit) return

this.addPlugin(new RendererPlugin(), { canvas })
.addPlugin(new ScenePlugin())
.addPlugin(new PCameraPlugin())
.addPlugin(new AnimationPlugin())
.addPlugin(new ResizePlugin())

this.isInit = true
}
}
Loading

0 comments on commit 4cb68de

Please sign in to comment.