From 7de39ba93eb17c78f32c04659087f29b4c6739d2 Mon Sep 17 00:00:00 2001 From: cx Date: Fri, 4 Aug 2017 00:02:09 +0800 Subject: [PATCH] =?UTF-8?q?Db=20=E4=B8=8EView=E5=B1=82=E5=88=86=E7=A6=BB?= =?UTF-8?q?=20=20=E5=88=86=E7=A6=BB=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=9A=84=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __test__/Draw.ts | 61 ++++++++ src/ApplicationServices/Application.ts | 6 +- src/DatabaseServices/Database.ts | 62 ++++++-- src/DatabaseServices/Entity.ts | 146 +++++++++++------- src/DatabaseServices/EntityData.quo.ts | 3 + src/DatabaseServices/EntityData.ts | 7 +- src/GraphicsSystem/Enum.ts | 13 ++ src/GraphicsSystem/GripScene.ts | 2 - src/GraphicsSystem/RenderPerformanceStatus.ts | 33 ++++ src/GraphicsSystem/Viewer.ts | 62 +++++--- 10 files changed, 303 insertions(+), 92 deletions(-) create mode 100644 __test__/Draw.ts create mode 100644 src/GraphicsSystem/Enum.ts create mode 100644 src/GraphicsSystem/RenderPerformanceStatus.ts diff --git a/__test__/Draw.ts b/__test__/Draw.ts new file mode 100644 index 000000000..43e42ca08 --- /dev/null +++ b/__test__/Draw.ts @@ -0,0 +1,61 @@ +import * as THREE from 'three'; +import { Vector3 } from 'three'; + + + +//绘制线 +function DrawLine(sp: THREE.Vector3, ep: THREE.Vector3): THREE.Object3D +{ + //创建几何体 + var geometry = new THREE.Geometry(); + geometry.vertices.push(sp.clone()); + geometry.vertices.push(ep.clone()); + + //创建材质 + var material = new THREE.LineBasicMaterial(); + let threeObject: THREE.Object3D = new THREE.Line(geometry, material); + + return threeObject; +} + +function SetLinePoint(line: THREE.Object3D, pt: THREE.Vector3) +{ + let l: THREE.Line = line; + + let geo: THREE.Geometry = l.geometry; + + geo.vertices[0].set(pt.x, pt.y, pt.z); + + geo.verticesNeedUpdate = true; +} + +/** + * + * + * @param {THREE.Object3D} ent + * @param {boolean} isSet + */ +function SetIsSelect(ent: THREE.Object3D, isSet: boolean) +{ + var baseColor = 0x333333; + var foundColor = 0x12C0E3; + var intersectColor = 0x00D66B; + + let mesh = ent; + + let material = mesh.material; + + if (isSet) + { + material.color.setHex(intersectColor); + } + else + { + material.color.setHex(baseColor); + } +} + +function CreateBox(l: number, w: number, h: number) +{ + var geometry = new THREE.BoxGeometry(l, w, h); +} \ No newline at end of file diff --git a/src/ApplicationServices/Application.ts b/src/ApplicationServices/Application.ts index abf4abac2..31ea6bec8 100644 --- a/src/ApplicationServices/Application.ts +++ b/src/ApplicationServices/Application.ts @@ -9,6 +9,7 @@ import { Editor } from '../Editor/Editor'; import { OBB } from '../Geometry/OBB/obb'; import { CoordinateSystem } from '../Geometry/CoordinateSystem'; import { CameraControls } from '../Editor/CameraControls'; +import { RenderPerformanceStatus } from '../GraphicsSystem/RenderPerformanceStatus'; export var app: ApplicationService export var ed: Editor export var db: Database @@ -25,8 +26,11 @@ export class ApplicationService //数据 this.m_Database = new Database(); //渲染器 - this.m_Viewer = new Viewer(document.getElementById("Webgl"), this.m_Database.m_Scene); + this.m_Viewer = new Viewer(document.getElementById("Webgl")); + this.m_Viewer.renderDatabase(this.m_Database); + //性能测试 + new RenderPerformanceStatus(this.m_Viewer); //相机控制 new CameraControls(this.m_Viewer, this.m_Viewer.m_Render.domElement); new DebugDatUi(); diff --git a/src/DatabaseServices/Database.ts b/src/DatabaseServices/Database.ts index 9c7c5cfac..ef51329a2 100644 --- a/src/DatabaseServices/Database.ts +++ b/src/DatabaseServices/Database.ts @@ -5,19 +5,25 @@ import { Entity } from './Entity'; import { ed } from '../ApplicationServices/Application'; import * as _ from "lodash"; import { IDataBaseData, DataBaseData } from './EntityData'; -export enum SceneType -{ - Wireframe = 0 -} + +/** + * 图形数据集合,一旦图形加入到集合,那么图形由集合控制. + * 并且View层可以通过该集合渲染出图形 + * 集合包括下列数据 + * -1.图形数据(id列表)只有Id列表. + * -2.字典数据(id列表)只有列表 + * -3.....等. + * + * @export + * @class Database + */ export class Database { - m_Data: IDataBaseData + private m_Data: IDataBaseData //场景 - m_Scene: THREE.Scene; m_EntityCollection: Map = new Map();//图形集合 constructor() { - this.m_Scene = new THREE.Scene(); this.initData(); } initData() @@ -35,15 +41,47 @@ export class Database ent.m_Db = this; ent.objectId = this.m_Data.allocateId(); this.m_EntityCollection.set(ent.objectId, ent); - this.m_Scene.add(ent.m_ThreeObj); ed.UpdateScreen(); } - removeEntity(ent: Entity) + getEntity(id: number): Entity + { + if (this.m_EntityCollection.has(id)) + { + return this.m_EntityCollection.get(id); + } + return null; + } + //删除 + removeEntity(ent: number) { - this.m_Scene.remove(ent.m_ThreeObj); + this.m_Data.removeEntity(ent); } - getScene(type: SceneType): THREE.Scene + + + /** + * 返回所有的id列表 + * + * @returns {Array} + * @memberof Database + */ + getObjectIdCollection(): Array + { + return this.m_Data.idColl; + } + getEntityCollection(): Array { - return this.m_Scene; + let res = [] + for (var ent in this.m_EntityCollection.values) + { + res.push(ent); + } + return res; + // return this.m_Data.idColl.map(id => + // { + // return this.getEntity(id); + // }).filter(e => + // { + // return e + // }) } } \ No newline at end of file diff --git a/src/DatabaseServices/Entity.ts b/src/DatabaseServices/Entity.ts index f46245f12..364ce86f6 100644 --- a/src/DatabaseServices/Entity.ts +++ b/src/DatabaseServices/Entity.ts @@ -2,21 +2,65 @@ import * as THREE from "three" import { OBB } from '../Geometry/OBB/obb'; import { Database } from './Database'; import { Vector3 } from 'three'; -import { IEntityData, EntityData, LineData, ILineData } from './EntityData'; +import { IEntityData, EntityData, LineData, ILineData, iSnapshotEntityData } from './EntityData'; +import * as mst from 'mobx-state-tree'; +import * as dat from 'dat.gui/build/dat.gui.js'; +import { RenderType } from "../GraphicsSystem/Enum"; +import { autorun } from 'mobx'; var baseColor = 0x333333; var foundColor = 0x12C0E3; var intersectColor = 0x00D66B; export class Entity { + /** + * 图形所属Db + * + * @type {Database} + * @memberof Entity + */ m_Db: Database; - m_ThreeObj: THREE.Object3D; + + + /** + * 图形数据 + * + * @protected + * @type {IEntityData} + * @memberof Entity + */ protected m_Data: IEntityData; + /** + * 缓存图形集合. + * + * @protected + * @type {Map} + * @memberof Entity + */ + protected m_DrawEntity: Map = new Map(); + constructor() { this.initData(); } + /** + * + * @param data 快照数据 用于还原 + */ + dataIn(data: iSnapshotEntityData) + { + mst.applySnapshot(this.m_Data, data); + } + dataOut(): iSnapshotEntityData + { + return mst.getSnapshot(this.m_Data); + } + + Draw(renderType: RenderType): THREE.Object3D + { + return null; + } get objectId(): number { @@ -37,13 +81,13 @@ export class Entity } erase(isErase: boolean = true) { - this.m_Db.removeEntity(this); + this.m_Data.setErase(isErase); } getBox(): THREE.Box3 { let box = new THREE.Box3(); - box.setFromObject(this.m_ThreeObj); + // box.setFromObject(this.m_ThreeObj); return box; } @@ -56,7 +100,8 @@ export class Entity { let obb = new OBB(); let size = this.Size; - obb.m_CoordinateSystem.copyForm(this.m_ThreeObj.matrix); + // obb.m_CoordinateSystem.copyForm(this.m_ThreeObj.matrix); + obb.m_CoordinateSystem.m_Postion.sub(obb.m_CoordinateSystem.m_xAxis.clone().multiplyScalar(size.x * 0.5)); obb.m_CoordinateSystem.m_Postion.sub(obb.m_CoordinateSystem.m_yAxis.clone().multiplyScalar(size.y * 0.5)); obb.m_CoordinateSystem.m_Postion.sub(obb.m_CoordinateSystem.m_zAxis.clone().multiplyScalar(size.z * 0.5)); @@ -65,29 +110,11 @@ export class Entity } applyMatrix4(mat: THREE.Matrix4) { - if (this.m_ThreeObj) - { - this.m_ThreeObj.applyMatrix(mat) - } + } setIsSelct(bool: boolean) { - if (this.m_ThreeObj && this.m_ThreeObj instanceof THREE.Mesh) - { - if (this.m_ThreeObj.material instanceof THREE.MeshBasicMaterial) - { - - if (bool) - { - this.m_ThreeObj.material.color.setHex(intersectColor); - } - else - { - this.m_ThreeObj.material.color.setHex(baseColor); - } - } - } } } @@ -102,23 +129,54 @@ export class Curve extends Entity export class Line extends Curve { - constructor(startPt: THREE.Vector3, endPt: THREE.Vector3) + constructor(startPt?: THREE.Vector3, endPt?: THREE.Vector3) { super(); let data = this.m_Data; - data.setStartPoint(startPt); - data.setEndPoint(endPt); - var geometry = new THREE.Geometry(); - geometry.vertices.push(data.StartPoint); - geometry.vertices.push(data.EndPoint); - //create a blue LineBasicMaterial - var material = new THREE.LineBasicMaterial(); - this.m_ThreeObj = new THREE.Line(geometry, material); + + if (startPt) + { + data.setStartPoint(startPt); + if (endPt) + data.setEndPoint(endPt); + } } initData() { this.m_Data = LineData.create(); } + private getData(): ILineData + { + return this.m_Data; + } + Draw(renderType: RenderType): THREE.Object3D + { + if (this.m_DrawEntity.has(renderType)) + { + return this.m_DrawEntity.get(renderType); + } + //创建几何体 + var geometry = new THREE.Geometry(); + let sp = this.getData().StartPoint; + let ep = this.getData().EndPoint; + geometry.vertices.push(sp); + geometry.vertices.push(ep); + + //TODO:创建材质..明显重复的 + var material = new THREE.LineBasicMaterial(); + let threeObject: THREE.Object3D = new THREE.Line(geometry, material); + + this.m_DrawEntity.set(renderType, threeObject); + + //事件注入. + autorun(() => + { + sp.copy(this.getData().StartPoint); + ep.copy(this.getData().EndPoint); + geometry.verticesNeedUpdate = true; + }) + return threeObject; + } GetGripPoints(): Array { return [this.StartPoint, this.EndPoint]; @@ -139,27 +197,11 @@ export class Line extends Curve //http://jsfiddle.net/hjx3rLmt/1/ setStartPoint(pt: THREE.Vector3) { - if (this.m_ThreeObj instanceof THREE.Line) - { - if (this.m_ThreeObj.geometry instanceof THREE.Geometry) - { - this.m_ThreeObj.geometry.vertices[0].set(pt.x, pt.y, pt.z); - - this.m_ThreeObj.geometry.verticesNeedUpdate = true; - } - } + this.getData().setStartPoint(pt); } setEndPoint(pt: THREE.Vector3) { - if (this.m_ThreeObj instanceof THREE.Line) - { - if (this.m_ThreeObj.geometry instanceof THREE.Geometry) - { - this.m_ThreeObj.geometry.vertices[1].set(pt.x, pt.y, pt.z); - - this.m_ThreeObj.geometry.verticesNeedUpdate = true; - } - } + this.getData().setEndPoint(pt); } } @@ -170,8 +212,6 @@ export class Solid3d extends Entity super(); let size = this.Size; size.set(len, wid, hei) - var geometry = new THREE.BoxGeometry(len, wid, hei); - this.m_ThreeObj = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial); } applyMatrix4(mat: THREE.Matrix4) { diff --git a/src/DatabaseServices/EntityData.quo.ts b/src/DatabaseServices/EntityData.quo.ts index 68c61dd5a..dcea0caf9 100644 --- a/src/DatabaseServices/EntityData.quo.ts +++ b/src/DatabaseServices/EntityData.quo.ts @@ -47,6 +47,9 @@ class L extends E { let l = new L() + + + let a: (typeof EntityData.SnapshotType) = mst.getSnapshot(l.m_Data); console.log(mst.getSnapshot(l.m_Data)); let snp = mst.getSnapshot(l.m_Data); diff --git a/src/DatabaseServices/EntityData.ts b/src/DatabaseServices/EntityData.ts index 5e5e35e28..64744a741 100644 --- a/src/DatabaseServices/EntityData.ts +++ b/src/DatabaseServices/EntityData.ts @@ -38,6 +38,7 @@ export const EntityData = mst.types.model( } ) export type IEntityData = typeof EntityData.Type; +export type iSnapshotEntityData = typeof EntityData.SnapshotType; export const CurveData = mst.types.compose( "Curve", @@ -84,7 +85,7 @@ export const DataBaseData = mst.types.model( /** * 图形列表 使用ID存储 */ - idList: mst.types.optional(mst.types.array(mst.types.number), []), + idColl: mst.types.optional(mst.types.array(mst.types.number), []), /** * 当前图元个数 */ @@ -93,11 +94,11 @@ export const DataBaseData = mst.types.model( { addEntity(id: number) { - this.idList.push(id); + this.idColl.push(id); }, removeEntity(id: number) { - this.idList.remove(id); + this.idColl.remove(id); }, allocateId(): number { diff --git a/src/GraphicsSystem/Enum.ts b/src/GraphicsSystem/Enum.ts new file mode 100644 index 000000000..1156d12ac --- /dev/null +++ b/src/GraphicsSystem/Enum.ts @@ -0,0 +1,13 @@ +/** + * 场景的渲染类型. + * + * @export + * @enum {number} + */ +export enum RenderType +{ + /** + * 线框模式 + */ + Wireframe = 1 +} \ No newline at end of file diff --git a/src/GraphicsSystem/GripScene.ts b/src/GraphicsSystem/GripScene.ts index 3a9db3c6e..7990e7a9b 100644 --- a/src/GraphicsSystem/GripScene.ts +++ b/src/GraphicsSystem/GripScene.ts @@ -6,8 +6,6 @@ export class GripScene extends THREE.Scene constructor() { super() - let line = new Line(new THREE.Vector3(), new THREE.Vector3(100, 10, 0)) - this.add(line.m_ThreeObj) } } \ No newline at end of file diff --git a/src/GraphicsSystem/RenderPerformanceStatus.ts b/src/GraphicsSystem/RenderPerformanceStatus.ts new file mode 100644 index 000000000..80dc7212e --- /dev/null +++ b/src/GraphicsSystem/RenderPerformanceStatus.ts @@ -0,0 +1,33 @@ +import { Viewer } from './Viewer'; +import * as xaop from 'xaop'; +import Stats = require('stats.js') + + +/** + * 渲染性能状态查看器. 在DOM上显示一个渲染帧数 + * + * @export + * @class RenderPerformanceStatus + */ +export class RenderPerformanceStatus +{ + m_Stats: Stats; + constructor(view: Viewer) + { + this.m_Stats = new Stats(); + this.m_Stats.showPanel(0); + this.m_Stats.dom.style.top = "36px"; + document.body.appendChild(this.m_Stats.dom); + + //aop注入. + + xaop.begin(view, view.Render, () => + { + this.m_Stats.begin(); + }) + xaop.end(view, view.Render, () => + { + this.m_Stats.end(); + }) + } +} \ No newline at end of file diff --git a/src/GraphicsSystem/Viewer.ts b/src/GraphicsSystem/Viewer.ts index 17fbfa696..2f2b6c70f 100644 --- a/src/GraphicsSystem/Viewer.ts +++ b/src/GraphicsSystem/Viewer.ts @@ -1,11 +1,12 @@ -import { Database } from "../DatabaseServices/Database"; +import { Database } from '../DatabaseServices/Database'; import { Camera } from "./Camera"; import * as THREE from "three"; -import { Line } from '../DatabaseServices/Entity'; +import { Line, Entity } from '../DatabaseServices/Entity'; import { GripScene } from './GripScene'; -import Stats = require('stats.js') +import { RenderType } from "./Enum"; +import * as xaop from 'xaop'; // const maxXRo = Math.PI * 0.5; @@ -24,27 +25,55 @@ export class Viewer m_Render: THREE.WebGLRenderer; //暂时只用这个类型 //相机类 m_Camera: Camera; + + m_RenderType: RenderType; //场景 引用自数据库 - m_Scene: THREE.Scene;//private + m_Scene: THREE.Scene = new THREE.Scene(); private m_GripScence: GripScene = new GripScene; m_HtmlElement: HTMLElement; - - m_Stats: Stats; //构造 - constructor(canvas: HTMLElement, scene: THREE.Scene) + constructor(canvas: HTMLElement) { - this.m_Stats = new Stats(); - this.m_Stats.showPanel(0); - this.m_Stats.dom.style.top = "36px"; - document.body.appendChild(this.m_Stats.dom); this.m_HtmlElement = canvas; - this.setScene(scene); this.initRender(); this.initCamera(); //渲染循环 this.Render(); } + //TODO: 假设我现在只渲染一个数据层. 不渲染多个. + renderDatabase(db: Database) + { + let ens = db.getEntityCollection(); + let injectEntity = (ent: Entity) => + { + xaop.begin(ent, ent.erase, (b: boolean) => + { + if (b) + { + let obj = ent.Draw(this.m_RenderType); + obj.visible = !b; + } + }) + } + ens.forEach(e => + { + injectEntity(e); + let obj = e.Draw(this.m_RenderType); + this.m_Scene.add(obj); + }) + //事件注入 + xaop.begin(db, db.appendEntity, (ent: Entity) => + { + injectEntity(ent); + this.m_Scene.add(ent.Draw(this.m_RenderType)); + }) + xaop.begin(db, db.removeEntity, (id: number) => + { + let ent = db.getEntity(id); + this.m_Scene.remove(ent.Draw(this.m_RenderType)); + }) + } getAspectRatio(): number { return this.m_HtmlElement.scrollWidth / this.m_HtmlElement.scrollHeight; @@ -72,13 +101,6 @@ export class Viewer pt.x += this.m_HtmlElement.scrollWidth * 0.5; pt.y += this.m_HtmlElement.scrollHeight * 0.5; } - - //设置渲染场景 - setScene(scene: THREE.Scene) - { - this.m_Scene = scene; - } - onSize = () => { console.log(this.m_HtmlElement.clientWidth); @@ -130,7 +152,6 @@ export class Viewer Render = () => { requestAnimationFrame(this.Render); - this.m_Stats.begin(); if (this.m_Scene != null && this.m_bIsChange) { this.m_Render.clear(); @@ -139,7 +160,6 @@ export class Viewer this.m_Render.render(this.m_GripScence, this.m_Camera.m_CurCamera); } - this.m_Stats.end(); } Pan(v: THREE.Vector3) {