CADViewComponent/src/Viewer.ts

195 lines
5.8 KiB
TypeScript
Raw Normal View History

import * as THREE from "three";
import { CameraUpdate } from "./CameraUpdate";
import { GetBox, GetBoxArr, cZeroVec } from "./GeUtils";
import { PlaneExt } from "./PlaneExt";
import { PointPick, boardMaterial, CameraControls } from ".";
import { MeshBasicMaterial, Color, Mesh } from "three";
export class Viewer
{
m_LookTarget: any;
m_Camera: CameraUpdate = new CameraUpdate();
m_bNeedUpdate: boolean = true;
m_Render: THREE.WebGLRenderer;//渲染器 //暂时只用这个类型
m_DomEl: HTMLElement; //画布容器
_Height: number;
_Width: number;
m_Scene: THREE.Scene = new THREE.Scene();
//构造
constructor(canvasContainer: HTMLElement)
{
this.m_DomEl = canvasContainer;
this.initRender(canvasContainer);
this.OnSize();
this.StartRender();
new CameraControls(this);
window.addEventListener("resize", () =>
{
this.OnSize();
});
//选中
let selectMaterial = new MeshBasicMaterial({ color: new Color(0.1, 0.5, 0.5) });
let oldMesh: Mesh;
this.m_Render.domElement.addEventListener("mousemove", (e: MouseEvent) =>
{
let mesh = PointPick(this, e.offsetX, e.offsetY);
if (oldMesh)
oldMesh.material = boardMaterial;
if (mesh)
{
oldMesh = mesh;
mesh.material = selectMaterial;
this.m_bNeedUpdate = true;
}
})
}
//初始化render
initRender(canvasContainer: HTMLElement)
{
this.m_Render = new THREE.WebGLRenderer(
{
antialias: true,//antialias:true/false是否开启反锯齿
precision: "highp",//precision:highp/mediump/lowp着色精度选择
alpha: true,//alpha:true/false是否可以设置背景色透明
// premultipliedAlpha: false,//?
// stencil: false,//?
// preserveDrawingBuffer: true,//preserveDrawingBuffer:true/false是否保存绘图缓冲
// maxLights: 1//maxLights:最大灯光数
}
);
//加到画布
canvasContainer.appendChild(this.m_Render.domElement);
this.m_Render.autoClear = true;
//如果设置那么它希望所有的纹理和颜色都是预乘的伽玛。默认值为false。
// this.m_Render.gammaInput = true;
// this.m_Render.gammaOutput = true;
// this.m_Render.shadowMap.enabled = true;
// this.m_Render.toneMapping = THREE.ReinhardToneMapping;
//设置设备像素比。 这通常用于HiDPI设备以防止模糊输出画布。
this.m_Render.setPixelRatio(window.devicePixelRatio);
this.m_Render.physicallyCorrectLights = true;
//this.m_Render.toneMappingExposure = Math.pow(1, 5.0); // to allow for very bright scenes.
//设置它的背景色为黑色
this.m_Render.setClearColor(0xffffff, 1);
this.OnSize();
}
OnSize = (width?, height?) =>
{
this._Width = width ? width : this.m_DomEl.scrollWidth;
this._Height = height ? height : this.m_DomEl.scrollHeight;
//校验.成为2的倍数 避免外轮廓错误.
if (this._Width % 2 == 1)
this._Width -= 1;
if (this._Height % 2 == 1)
this._Height -= 1;
this.m_Render.setSize(this._Width, this._Height);
this.m_Camera.SetSize(this._Width, this._Height);
}
StartRender = () =>
{
requestAnimationFrame(this.StartRender);
if (this.m_Scene != null && this.m_bNeedUpdate)
{
this.Render();
this.m_bNeedUpdate = false;
}
}
Render()
{
this.m_Render.render(this.m_Scene, this.m_Camera.Camera);
}
ScreenToWorld(pt: THREE.Vector3, planVec?: THREE.Vector3)
{
//变换和求交点
let plan = new PlaneExt(planVec || new THREE.Vector3(0, 0, 1));
let raycaster = new THREE.Raycaster();
// 射线从相机射线向屏幕点位置
raycaster.setFromCamera(
{
x: (pt.x / this._Width) * 2 - 1,
y: - (pt.y / this._Height) * 2 + 1
}
, this.m_Camera.Camera
)
plan.intersectRay(raycaster.ray, pt, true);
}
WorldToScreen(pt: THREE.Vector3)
{
let widthHalf = this._Width * 0.5;
let heightHalf = this._Height * 0.5;
pt.project(this.m_Camera.Camera);
pt.x = (pt.x * widthHalf) + widthHalf;
pt.y = - (pt.y * heightHalf) + heightHalf;
}
/**
* ()
*
* @memberof Viewer
*/
UpdateLockTarget()
{
let renderList = this.m_Render.renderLists.get(this.m_Scene, this.m_Camera.Camera);
let box = GetBoxArr(renderList.opaque.map(o => o.object));
if (box)
this.m_LookTarget = box.getCenter(new THREE.Vector3());
else
this.m_LookTarget = cZeroVec;
}
Rotate(mouseMove: THREE.Vector3)
{
this.m_Camera.Rotate(mouseMove, this.m_LookTarget);
this.m_bNeedUpdate = true;
}
Pan(mouseMove: THREE.Vector3)
{
this.m_Camera.Pan(mouseMove);
this.m_bNeedUpdate = true;
}
Zoom(scale: number, center?: THREE.Vector3)
{
this.m_Camera.Zoom(scale, center);
this.m_bNeedUpdate = true;
}
ZoomAll()
{
this.m_Camera.ZoomExtensBox3(GetBox(this.m_Scene, true));
this.m_bNeedUpdate = true;
}
ViewToTop()
{
this.m_Camera.LookAt(new THREE.Vector3(0, 0, -1));
this.m_bNeedUpdate = true;
}
ViewToFront()
{
this.m_Camera.LookAt(new THREE.Vector3(0, 1, 0));
this.m_bNeedUpdate = true;
}
ViewToSwiso()
{
this.m_Camera.LookAt(new THREE.Vector3(1, 1, -1));
this.m_bNeedUpdate = true;
}
}