pull/7/head
FishOrBear 7 years ago
parent 9c2ac4cab8
commit 06f7c6f867

@ -0,0 +1,3 @@
//
{
}

@ -22,6 +22,9 @@ npm run start
安装: npm install react-dat-gui --save
说明: https://www.npmjs.com/package/react-dat-gui
#dat.gui 白色风格
http://www.sw-engineering-candies.com/blog-1/improved-css-for-dat-gui-in-light-web-pages
#React github
链接: https://github.com/brillout/awesome-react-components
@ -57,12 +60,19 @@ http://jsfiddle.net/m1erickson/CtsY3/
#网格拉伸夹点
https://threejs.org/examples/?q=m#webgl_morphtargets
#渲染循环优化
https://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
#type
https://msdn.microsoft.com/en-us/magazine/dn890374.aspx
https://www.typescriptlang.org/docs/handbook/classes.html
https://github.com/Microsoft/TypeScript/issues/1524
#解决 Stats.js
https://www.typescriptlang.org/docs/handbook/modules.html
http://stackoverflow.com/questions/12930049/how-do-i-import-other-typescript-files
http://stackoverflow.com/questions/18556187/importing-typescript-modules
//TODO:
1.相机.
>注册相机事件 尝试优化相机

@ -30,10 +30,11 @@
"dependencies": {
"@types/dat-gui": "^0.6.2",
"@types/lodash": "^4.14.64",
"@types/stats": "^0.16.30",
"@types/stats.js": "^0.16.0",
"@types/three": "^0.84.7",
"dat.gui": "^0.6.1",
"lodash": "^4.17.4",
"stats.js": "^0.17.0",
"three": "^0.85.2"
}
}
}

@ -9,6 +9,7 @@ import { Viewer } from "./GraphicsSystem/Viewer";
import { CameraControls } from "./GraphicsSystem/Camera";
import { Entity, Line, Solid3d } from "./DatabaseServices/Entity";
import { DebugDatUi } from "./Editor/DebugDatUi";
@ -198,8 +199,10 @@ export class Application2
this.m_Database.appendEntity(line);
this.m_Viewer.m_bIsChange = true;
//绘制方块
// var box = new Solid3d(100, 200, 300);
// this.m_Database.appendEntity(box);
var box = new Solid3d(100, 200, 300);
this.m_Database.appendEntity(box);
new DebugDatUi();
}
static Application: Application2;

@ -0,0 +1,33 @@
import * as THREE from 'three'
import { Viewer } from "../GraphicsSystem/Viewer";
import { Entity } from "./Entity";
export enum SceneType
{
Wireframe = 0
}
export class Database
{
//场景
m_Scene: THREE.Scene;
m_EntityCollection: Array<Entity> = [];//图形集合
constructor()
{
this.m_Scene = new THREE.Scene();
}
//添加图元到数据对象
appendEntity(ent: Entity)
{
this.m_EntityCollection.push(ent);
this.m_Scene.add(ent.m_ThreeObj);
}
getScene(type: SceneType): THREE.Scene
{
//TODO: 返回指定类型的场景
return this.m_Scene;
}
}

@ -0,0 +1,45 @@
import * as THREE from "three"
export class Entity
{
m_ThreeObj: THREE.Object3D;
}
export class Curve extends Entity
{
constructor()
{
super();
}
}
export class Line extends Curve
{
private m_StartPoint: THREE.Vector3 = new THREE.Vector3();
private m_EndPoint: THREE.Vector3 = new THREE.Vector3();
constructor(startPt: THREE.Vector3, endPt: THREE.Vector3)
{
super();
this.m_StartPoint.copy(startPt);
this.m_EndPoint.copy(endPt);
var geometry = new THREE.Geometry();
geometry.vertices.push(startPt);
geometry.vertices.push(endPt);
//create a blue LineBasicMaterial
var material = new THREE.LineBasicMaterial();
this.m_ThreeObj = new THREE.Line(geometry, material);
}
}
export class Solid3d extends Entity
{
constructor(len: number, wid: number, hei: number)
{
super();
var geometry = new THREE.BoxGeometry(len, wid, hei);
this.m_ThreeObj = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial);
}
}

@ -0,0 +1,32 @@
import * as dat from "dat.gui"
import { Application2 } from "../Application";
export class DebugDatUi
{
//UI.
m_Ctrl_UI: dat.GUI;
//Testz
z: number = 0;
arr: string = "a";
color: string = "#ffae23";
constructor()
{
this.m_Ctrl_UI = new dat.GUI(
{
autoPlace: true,
width: 555,
}
);
this.m_Ctrl_UI.add(this, "z");
this.m_Ctrl_UI.add(this, "arr", ["a", "b"]);
var change = this.m_Ctrl_UI.addColor(this, "color");
change.onChange((value: any) =>
{
Application2.Application.m_Viewer.m_Render.setClearColor(this.color);
Application2.Application.m_Viewer.m_bIsChange = true;
})
}
}

@ -0,0 +1,214 @@
//组合相机.
//这个相机可以随意切换相机.
import * as THREE from "three"
import { Viewer } from "./Viewer";
//相机类.
//https://www.youtube.com/watch?v=k3adBAnDpos
export class Camera
{
m_CurCamera: THREE.Camera;
m_ParentViewer: Viewer;
constructor(view: Viewer)
{
this.m_ParentViewer = view;
let viewHeight = view.m_ViewHeight;
var aspectRatio = window.innerWidth / window.innerHeight;
this.m_CurCamera = new THREE.OrthographicCamera(
aspectRatio * viewHeight / -2,
aspectRatio * viewHeight / 2,
viewHeight / 2,
viewHeight / -2,
-300, 300);
this.m_CurCamera.position.set(0, 0, 30);
var mat = new THREE.Matrix4();
}
Pan(v: THREE.Vector3)
{
let viewHeight = this.m_ParentViewer.m_ViewHeight;
var aspectRatio = this.m_ParentViewer.m_HtmlElement.offsetWidth / this.m_ParentViewer.m_HtmlElement.offsetHeight;
// var aspectRatio = window.innerWidth / window.innerHeight;
v.x *= -1;
v.multiplyScalar(viewHeight / this.m_ParentViewer.m_HtmlElement.offsetHeight);
if (this.m_CurCamera instanceof THREE.PerspectiveCamera)
{
// perspective
const position = this.m_CurCamera.position;
this.m_CurCamera.position.add(v);
}
else if (this.m_CurCamera instanceof THREE.OrthographicCamera)
{
let p = this.m_CurCamera.position;
this.m_CurCamera.position.add(v);
// this.m_CurCamera.up.set(0, 0, -1);
this.m_CurCamera.lookAt(new THREE.Vector3(p.x, p.y, 0));
}
else
{
}
}
UpdateHeight()
{
let viewHeight = this.m_ParentViewer.m_ViewHeight;
var aspectRatio = window.innerWidth / window.innerHeight;
if (this.m_CurCamera instanceof THREE.OrthographicCamera)
{
this.m_CurCamera.left = aspectRatio * viewHeight / -2;
this.m_CurCamera.right = aspectRatio * viewHeight / 2;
this.m_CurCamera.bottom = viewHeight / -2;
this.m_CurCamera.top = viewHeight / 2;
this.m_CurCamera.updateProjectionMatrix();
}
}
}
//控制状态
enum State
{
Null = 0, Pan = 1, Rotate = 2, Scale = 3
}
//控制类型
enum CameraControlsEnabled
{
Rotate = 1,
Zoom = 2,
Pan = 4,
}
//
enum ButtonKey
{
Left = 0,
Middle = 1,
Right = 2,
}
//相机控制
export class CameraControls
{
m_domElement: HTMLElement | HTMLDocument;
m_window: Window;
//起始点击.
m_StartChickPoint: THREE.Vector3 = new THREE.Vector3();
m_EndChickPoint: THREE.Vector3 = new THREE.Vector3();
m_bKeyCtrlIsDown: boolean;
//状态
m_State: State = State.Null;
m_Viewer: Viewer;
constructor(viewer: Viewer, domElement?: HTMLElement, docWindow?: Window)
{
this.m_Viewer = viewer;
this.m_domElement = domElement ? domElement : document;
if (docWindow)
{
this.m_window = docWindow;
}
this.RegisterEvent();
}
RegisterEvent()
{
if (this.m_domElement)
{
this.m_domElement.addEventListener("mousedown", this.onMouseDown, false)
this.m_domElement.addEventListener("mousemove", this.onMouseMove, false)
this.m_domElement.addEventListener("mouseup", this.onMouseUp, false)
window.addEventListener("keydown", this.onKeyDown, false);
this.m_domElement.addEventListener('wheel', this.onMouseWheel, false);
}
}
//鼠标
onMouseDown = (event: MouseEvent) =>
{
event.preventDefault();
let key: ButtonKey = event.button;
this.m_StartChickPoint.set(event.clientX, event.clientY, 0);
switch (key)
{
case ButtonKey.Left:
{
break;
}
case ButtonKey.Middle:
{
if (this.m_bKeyCtrlIsDown)
{
this.m_State = State.Rotate;
}
else
{
this.m_State = State.Pan;
}
break;
}
case ButtonKey.Right:
{
break;
}
}
}
onMouseUp = (event: MouseEvent) =>
{
event.preventDefault();
this.m_State = State.Null;
}
onMouseMove = (event: MouseEvent) =>
{
event.preventDefault();
this.m_EndChickPoint.set(event.clientX, event.clientY, 0);
let changeVec: THREE.Vector3 = new THREE.Vector3();
changeVec.subVectors(this.m_EndChickPoint, this.m_StartChickPoint);
this.m_StartChickPoint.copy(this.m_EndChickPoint);
switch (this.m_State)
{
case State.Pan:
{
this.m_Viewer.Pan(changeVec);
break;
}
case State.Rotate:
{
break;
}
case State.Scale:
{
break;
}
}
}
onMouseWheel = (event: WheelEvent) =>
{
event.preventDefault();
event.stopPropagation();
console.log(event.deltaY);
if (event.deltaY < 0)
{
this.m_Viewer.Zoom(0.6);
} else if (event.deltaY > 0)
{
this.m_Viewer.Zoom(1.4);
}
}
//按键
onKeyDown = (event: KeyboardEvent) =>
{
switch (event.key)
{
case "Ctrl":
{
break;
}
}
}
onKeyUp = (event: KeyboardEvent) =>
{
}
}

@ -0,0 +1,101 @@
import { Database } from "../DatabaseServices/Database";
import { Camera } from "./Camera";
import * as THREE from "three";
import Stats = require('stats.js')
export class Viewer
{
m_ViewHeight: number = 205;
m_bIsChange: boolean = true;
//渲染器
m_Render: THREE.WebGLRenderer; //暂时只用这个类型
//相机类
m_Camera: Camera;
//场景 引用自数据库
private m_Scene: THREE.Scene;
m_HtmlElement: HTMLElement;
m_Stats: Stats;
//构造
constructor(canvas: HTMLElement, scene: THREE.Scene)
{
this.m_Stats = new Stats();
this.m_Stats.showPanel(1);
document.body.appendChild(this.m_Stats.dom);
this.m_HtmlElement = canvas;
this.setScene(scene);
this.initRender();
this.initCamera();
//加到画布
canvas.appendChild(this.m_Render.domElement);
//渲染循环
this.Render();
}
//设置渲染场景
setScene(scene: THREE.Scene)
{
this.m_Scene = scene;
}
//初始化render
initRender()
{
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:最大灯光数
}
);
this.m_Render.gammaInput = true;
this.m_Render.gammaOutput = true;
this.m_Render.shadowMap.enabled = true;
this.m_Render.toneMapping = THREE.ReinhardToneMapping;
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.
//设置设备像素比。 这通常用于HiDPI设备以防止模糊输出画布。
this.m_Render.setPixelRatio(window.devicePixelRatio);
//这里暂时初始化成这个. 未来将分离出 Viewer
this.m_Render.setSize(window.innerWidth - 30, window.innerHeight - 30);
//设置它的背景色为白色
this.m_Render.setClearColor(0x000000, 0.5);
}
//初始化相机
initCamera()
{
this.m_Camera = new Camera(this);
}
Render = () =>
{
requestAnimationFrame(this.Render);
this.m_Stats.begin();
if (this.m_Scene != null && this.m_bIsChange)
{
this.m_bIsChange = false;
this.m_Render.render(this.m_Scene, this.m_Camera.m_CurCamera);
}
this.m_Stats.end();
}
Pan(v: THREE.Vector3)
{
this.m_Camera.Pan(v);
this.m_bIsChange = true;
}
Zoom(scale: number)
{
this.m_bIsChange = true
this.m_ViewHeight *= scale;
this.m_Camera.UpdateHeight();
}
}

@ -1,6 +1,7 @@
import { Application, Application2 } from "./Application";
window.onload = function ()
{
new Application2();
};

@ -13,7 +13,7 @@ module.exports = {
resolve: {
alias: {
"dat.gui": path.resolve(__dirname, './node_modules/dat.gui/build/dat.gui.js'),
// "stats-js": path.resolve(__dirname, './node_modules/stats-js/build/stats.min.js'),
"stats-js": path.resolve(__dirname, './node_modules/stats.js/src/stats.js')
},
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".webpack.js", ".web.js", ".ts", ".tsx", ".js"]

Loading…
Cancel
Save