增加fbx加载 灯光加载代码 相机控制支持观察点锁定.

pull/7/head
ChenX 7 years ago
parent 0389cc8093
commit 826e403a57

@ -0,0 +1,12 @@
// window["t"] = () =>
// {
// app.m_Database.StartTransaction();
// let line = new Line(new THREE.Vector3(Math.random() * 100, Math.random() * 100), new THREE.Vector3(Math.random() * 100, Math.random() * 100))
// app.m_Database.appendEntity(line);
// app.m_Database.CommitTransaction();
// }

@ -0,0 +1,7 @@
//创建半球光
function CreateHemisphereLight()
{
var hemiLight = new THREE.HemisphereLight(0xddeeff, 0x0f0e0d, 1);
// app.m_Viewer.m_Scene.add(hemiLight);
}

@ -0,0 +1,47 @@
//加载事件
var onProgress = function (xhr)
{
if (xhr.lengthComputable)
{
var percentComplete = xhr.loaded / xhr.total * 100;
console.log(Math.round(percentComplete) + '% downloaded');
}
};
//错误事件
var onError = function (xhr)
{
console.error(xhr);
};
//Loader FBX
function loadFBX(fileName: string)
{
var manager = new THREE.LoadingManager();
var loader = new THREE.FBXLoader(manager);
loader.load(fileName, function (object)
{
// app.m_Viewer.m_Scene.add(object);
}, onProgress, onError);
}
//材质加载
function loadTexture(fileName: string)
{
var manager = new THREE.LoadingManager();
// 材质
var textLoader: THREE.TextureLoader = new THREE.TextureLoader();
var texture: THREE.Texture = textLoader.load("019.jpg");
texture.wrapS = texture.wrapT = THREE.RepeatWrapping; // CHANGED
texture.offset.set(0, 0); // CHANGED
texture.repeat.set(0.002, 0.002); // CHANGED
texture.needsUpdate = true;
//
var material = new THREE.MeshPhongMaterial({ map: texture }); // front
}

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
</html>

@ -8,7 +8,8 @@
"dts": "tcm src -o ./src/UI/css_dts",
"build": "webpack --config dll.config.js &&webpack",
"i": "npm i && npm i -dev",
"test": "jest"
"test": "jest",
"ser": "node ./utils/server.js"
},
"private": true,
"author": "",
@ -74,4 +75,4 @@
"js"
]
}
}
}

@ -7,6 +7,10 @@ import { UndoData } from '../DatabaseServices/UndoData';
import { PromptStatus } from '../Editor/PromptResult';
import * as ReactDOM from 'react-dom';
//最小限度的使用这个模块. 所以提供了一个导出的头文件.
export var FBXLoader = require('three-FBXLoader');
window["threeZlib"] = require("zlib")
export class DrawLine implements Command
{
async exec()
@ -55,16 +59,45 @@ export class Redo implements Command
}
}
window["t"] = () =>
function updateUV(geometry)
{
// 据我所知没有自动计算UV的方法。
// 你必须计算自己。计算一个平面的紫外线是相当容易的,这个网站解释如何:计算纹理坐标
// 对于一个复杂的形状,我不知道如何。也许你可以检测平面。
// 编辑
// 这是一个平面表面的示例代码,(x, y, z)其中z = 0
app.m_Database.StartTransaction();
geometry.computeBoundingBox();
let line = new Line(new THREE.Vector3(Math.random() * 100, Math.random() * 100), new THREE.Vector3(Math.random() * 100, Math.random() * 100))
var max = geometry.boundingBox.max,
min = geometry.boundingBox.min;
var offset = new THREE.Vector2(0 - min.x, 0 - min.y);
var range = new THREE.Vector2(max.x - min.x, max.y - min.y);
var faces = geometry.faces;
app.m_Database.appendEntity(line);
if (!geometry.faceVertexUvs)
{
geometry.faceVertexUvs = [[]];
}
geometry.faceVertexUvs[0] = [];
for (var i = 0; i < faces.length; i++)
{
var v1 = geometry.vertices[faces[i].a],
v2 = geometry.vertices[faces[i].b],
v3 = geometry.vertices[faces[i].c];
app.m_Database.CommitTransaction();
geometry.faceVertexUvs[0].push([
new THREE.Vector2((v1.x + offset.x) / range.x, (v1.y + offset.y) / range.y),
new THREE.Vector2((v2.x + offset.x) / range.x, (v2.y + offset.y) / range.y),
new THREE.Vector2((v3.x + offset.x) / range.x, (v3.y + offset.y) / range.y)
]);
}
geometry.uvsNeedUpdate = true;
}

@ -0,0 +1,5 @@
import { app } from '../ApplicationServices/Application';
export function log(msg)
{
app.m_Editor.m_CommandStore.Prompt(msg);
}

@ -75,6 +75,10 @@ export class Entity
{
return this.m_Data.getSize();
}
set Size(v: THREE.Vector3)
{
this.m_Data.setSize(v.x, v.y, v.z);
}
initData()
{
this.m_Data = EntityData.create();
@ -110,7 +114,10 @@ export class Entity
}
applyMatrix4(mat: THREE.Matrix4)
{
this.m_DrawEntity.forEach(e =>
{
e.applyMatrix(mat);
})
}
setIsSelct(bool: boolean)
{
@ -210,14 +217,24 @@ export class Solid3d extends Entity
constructor(len: number, wid: number, hei: number)
{
super();
let size = this.Size;
size.set(len, wid, hei)
this.Size = new THREE.Vector3(len, wid, hei);
}
applyMatrix4(mat: THREE.Matrix4)
{
super.applyMatrix4(mat);
// Entity.prototype.applyMatrix4.call(this,mat)
}
Draw(renderType: RenderType): THREE.Object3D
{
if (this.m_DrawEntity.has(renderType))
{
return this.m_DrawEntity.get(renderType);
}
let geometry = new THREE.BoxGeometry(this.Size.x, this.Size.y, this.Size.z);
let mesh = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial);
this.m_DrawEntity.set(renderType, mesh);
return mesh;
}
}
export class Point extends Entity

@ -1,11 +1,10 @@
//相机控制
import * as THREE from "three";
import { Viewer } from '../GraphicsSystem/Viewer';
import { ed, MouseMove } from '../ApplicationServices/Application';
import { PlaneExt } from '../Geometry/Plane';
import { Line3 } from 'three';
import { MouseKey } from '../Common/KeyEnum';
import { GeUtils } from "../Geometry/GeUtils";
//控制类型
enum CameraControlsEnabled
{
@ -29,6 +28,11 @@ export class CameraControls
//起始点击
m_StartChickPoint: THREE.Vector3 = new THREE.Vector3();
m_EndChickPoint: THREE.Vector3 = new THREE.Vector3();
m_DollyStart: THREE.Vector2 = new THREE.Vector2();
m_DollyEnd: THREE.Vector2 = new THREE.Vector2();
m_KeyDown = new Map<string, boolean>();
m_bKeyCtrlIsDown: boolean;
//状态
m_State: CameraControlState = CameraControlState.Null;
@ -51,7 +55,80 @@ export class CameraControls
window.addEventListener("keydown", this.onKeyDown, false);
window.addEventListener("keyup", this.onKeyUp, false);
this.m_domElement.addEventListener('wheel', this.onMouseWheel, false);
this.m_domElement.addEventListener('touchstart', this.onTouchStart, false);
this.m_domElement.addEventListener('touchend', this.onTouchEnd, false);
this.m_domElement.addEventListener('touchmove', this.onTouchMove, false);
window.addEventListener("blur", () =>
{
this.m_KeyDown.clear();
})
}
}
//触屏
onTouchStart = (event: TouchEvent) =>
{
this.m_StartChickPoint.set(event.touches[0].pageX, event.touches[0].pageY, 0);
if (event.touches.length < 4)
{
if (event.touches.length == 2)
{
var dx = event.touches[0].pageX - event.touches[1].pageX;
var dy = event.touches[0].pageY - event.touches[1].pageY;
var distance = Math.sqrt(dx * dx + dy * dy);
this.m_DollyStart.set(0, distance);
}
let touchType = [CameraControlState.Rotate, CameraControlState.Scale, CameraControlState.Pan];
this.m_State = touchType[event.touches.length - 1];
}
}
onTouchEnd = (event: TouchEvent) =>
{
this.m_State = CameraControlState.Null;
}
onTouchMove = (event: TouchEvent) =>
{
event.preventDefault();
event.stopPropagation();
this.m_EndChickPoint.set(event.touches[0].pageX, event.touches[0].pageY, 0);
let vec = this.m_EndChickPoint.clone().sub(this.m_StartChickPoint);
switch (this.m_State)
{
case CameraControlState.Pan:
{
this.m_Viewer.Pan(vec);
break;
}
case CameraControlState.Scale:
{
var dx = event.touches[0].pageX - event.touches[1].pageX;
var dy = event.touches[0].pageY - event.touches[1].pageY;
var distance = Math.sqrt(dx * dx + dy * dy);
this.m_DollyEnd.set(0, distance);
if (distance > this.m_DollyStart.y)
{
this.m_Viewer.Zoom(0.95);
}
else
{
this.m_Viewer.Zoom(1.05)
}
this.m_DollyStart.copy(this.m_DollyEnd);
break;
}
case CameraControlState.Rotate:
{
this.m_Viewer.Rotate(vec.multiplyScalar(2), GeUtils.cZeroVec);
break;
}
}
this.m_StartChickPoint.copy(this.m_EndChickPoint);
this.m_Viewer.m_bIsChange = true;
}
//鼠标
@ -68,7 +145,7 @@ export class CameraControls
}
case MouseKey.Middle:
{
if (this["Shift"])
if (this.m_KeyDown.get("Alt"))
{
this.m_State = CameraControlState.Rotate;
}
@ -98,7 +175,7 @@ export class CameraControls
changeVec.subVectors(this.m_EndChickPoint, this.m_StartChickPoint);
this.m_StartChickPoint.copy(this.m_EndChickPoint);
if (this["Shift"] && this.m_State == CameraControlState.Rotate)
if (this.m_KeyDown.get("Alt") && this.m_State == CameraControlState.Rotate)
{
this.m_Viewer.Rotate(changeVec);
}
@ -138,10 +215,10 @@ export class CameraControls
//按键
onKeyDown = (event: KeyboardEvent) =>
{
this[event.key] = true;
this.m_KeyDown.set(event.key, true);
}
onKeyUp = (event: KeyboardEvent) =>
{
this[event.key] = false;
this.m_KeyDown.set(event.key, false);
}
}
}

@ -19,13 +19,12 @@ export class Camera
{
this.m_ParentViewer = view;
this.m_CurCamera = new THREE.OrthographicCamera(-2, 2, 2, -2,
-5000, 5000);
-50000, 50000);
this.UpdateDirection();
this.Update();
}
Pan(v: THREE.Vector3)
{
let viewHeight = this.m_ParentViewer.m_ViewHeight;
this.Update();
}
UpdateDirection()

@ -3,10 +3,11 @@
import { Database } from '../DatabaseServices/Database';
import { Camera } from "./Camera";
import * as THREE from "three";
import { Line, Entity } from '../DatabaseServices/Entity';
import { GripScene } from './GripScene';
import { RenderType } from "./Enum";
import * as xaop from 'xaop';
import { GeUtils } from "../Geometry/GeUtils";
import { Entity } from '../DatabaseServices/Entity';
//
const maxXRo = Math.PI * 0.5;
@ -143,9 +144,7 @@ export class Viewer
WorldToScreen(pt: THREE.Vector3)
{
this.m_Camera.m_CurCamera.updateMatrix();
let matInv = new THREE.Matrix4()
matInv.getInverse(this.m_Camera.m_CurCamera.matrix);
pt.applyMatrix4(matInv);
pt.applyMatrix4(this.m_Camera.m_CurCamera.matrixWorldInverse);
pt.multiplyScalar(this.m_HtmlElement.scrollHeight / this.m_ViewHeight)
pt.y *= -1
@ -231,13 +230,29 @@ export class Viewer
this.m_Camera.Update();
this.m_bIsChange = true;
}
//传入画布的变换
Rotate(v: THREE.Vector3)
/**
*
*
* @param {THREE.Vector3} v
* @param {THREE.Vector3} [target] . ,使 .
* @memberof Viewer
*/
Rotate(v: THREE.Vector3, target?: THREE.Vector3)
{
let oldX = this.m_xRo;
let roZ = -v.x * 0.003;
this.m_xRo += v.y * 0.003;
this.m_zRo -= v.x * 0.003;
this.m_zRo += roZ;
this.m_xRo = this.m_xRo > maxXRo ? maxXRo : this.m_xRo < minXRo ? minXRo : this.m_xRo;
let roX = this.m_xRo - oldX;
//缓存观察点
if (!target) target = GeUtils.cZeroVec;
let tempCenter = target.clone();
this.m_Camera.m_CurCamera.updateMatrix();
tempCenter.applyMatrix4(this.m_Camera.m_CurCamera.matrixWorldInverse);
this.m_Direction.z = - Math.sin(this.m_xRo);
let d = Math.abs(Math.cos(this.m_xRo));
@ -246,7 +261,14 @@ export class Viewer
this.m_Direction.normalize()
this.m_Camera.UpdateDirection();
this.m_Camera.Update();
//还原观察点
this.m_Camera.m_CurCamera.updateMatrix();
tempCenter.applyMatrix4(this.m_Camera.m_CurCamera.matrix);
this.m_Target.sub(tempCenter);
this.m_Camera.Update();
this.m_bIsChange = true;
}
}
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,52 @@
import { Viewer } from '../GraphicsSystem/Viewer';
import { Editor } from '../Editor/Editor';
import { CameraControls } from '../Editor/CameraControls';
/**
*
* view. view.
*
* @export
* @class WebCADView
*/
export class WebCADView
{
private m_View:Viewer;
m_Editor:Editor;
/**
* Creates an instance of WebCADView.
*
* ,dom..
*
* @param {HTMLElement} domNode
* @memberof WebCADView
*/
constructor(domNode:HTMLElement)
{
//渲染器
this.m_View = new Viewer(domNode);
//相机控制
new CameraControls(this.m_View, this.m_View.m_Render.domElement);
}
//加载场景.
Load(SceneData:Object)
{
}
//缩放到全部
ZoomAll()
{
}
//前视图
ViewToFont()
{
}
//俯视图
//西南等轴视图
}

@ -14,6 +14,8 @@ import { DownPanel } from './UI/Components/Panel';
import { DownPanelStore } from './UI/Store/DownPanelStore';
import { DrawLine, Undo, Redo } from './Add-on/DrawLine';
import { UndoData } from './DatabaseServices/UndoData';
import { Solid3d, Line } from './DatabaseServices/Entity';
import { Vector3 } from 'three';
function createRootElement()
{
var root = document.createElement('div');
@ -55,6 +57,9 @@ function initApp()
app.m_Editor.m_CommandMachine.m_CommandList.set("l", new DrawLine())
app.m_Editor.m_CommandMachine.m_CommandList.set("u", new Undo())
app.m_Editor.m_CommandMachine.m_CommandList.set("redo", new Redo())
// let box = new Solid3d(10, 10, 10);
// app.m_Database.appendEntity(box)
}
window.onload = function ()

@ -0,0 +1,110 @@
/**
* a barebones HTTP server in JS
* to serve three.js easily
*
* @author zz85 https://github.com/zz85
*
* Usage: node simplehttpserver.js <port number>
*
* do not use in production servers
* and try
* npm install http-server -g
* instead.
*/
var port = 8000,
http = require('http'),
urlParser = require('url'),
fs = require('fs'),
path = require('path'),
currentDir = process.cwd() + "\\dist";
port = process.argv[2] ? parseInt(process.argv[2], 0) : port;
function handleRequest(request, response)
{
var urlObject = urlParser.parse(request.url, true);
var pathname = decodeURIComponent(urlObject.pathname);
console.log('[' + (new Date()).toUTCString() + '] ' + '"' + request.method + ' ' + pathname + '"');
var filePath = path.join(currentDir, pathname);
if (pathname == "/") {
filePath = path.join(currentDir, "index.html");
}
fs.stat(filePath, function (err, stats)
{
if (err) {
response.writeHead(404, {});
response.end('File not found!');
return;
}
if (stats.isFile()) {
fs.readFile(filePath, function (err, data)
{
if (err) {
response.writeHead(404, {});
response.end('Opps. Resource not found');
return;
}
response.writeHead(200, {});
response.write(data);
response.end();
});
} else if (stats.isDirectory()) {
fs.readdir(filePath, function (error, files)
{
if (error) {
response.writeHead(500, {});
response.end();
return;
}
var l = pathname.length;
if (pathname.substring(l - 1) != '/') pathname += '/';
response.writeHead(200, { 'Content-Type': 'text/html' });
response.write('<!DOCTYPE html>\n<html><head><meta charset="UTF-8"><title>' + filePath + '</title></head><body>');
response.write('<h1>' + filePath + '</h1>');
response.write('<ul style="list-style:none;font-family:courier new;">');
files.unshift('.', '..');
files.forEach(function (item)
{
var urlpath = pathname + item,
itemStats = fs.statSync(currentDir + urlpath);
if (itemStats.isDirectory()) {
urlpath += '/';
item += '/';
}
response.write('<li><a href="' + urlpath + '">' + item + '</a></li>');
});
response.end('</ul></body></html>');
});
}
});
}
http.createServer(handleRequest).listen(port);
require('dns').lookup(require('os').hostname(), function (err, addr, fam)
{
console.log('Running at http://' + addr + ((port === 80) ? '' : ':') + port + '/');
});
console.log('Three.js server has started...');
console.log('Base directory at ' + currentDir);

@ -14,6 +14,8 @@ module.exports = {
resolve: {
alias: {
"dat.gui": path.resolve(__dirname, './node_modules/dat.gui/build/dat.gui.js'),
"three-FBXLoader": path.resolve(__dirname, "./src/Loader/FBXLoader.js"),
"zlib": path.resolve(__dirname, "./node_modules/three/examples/js/libs/inflate.min.js")
// "stats-js": path.resolve(__dirname, './node_modules/stats.js/src/stats.js'),
},
// Add '.ts' and '.tsx' as resolvable extensions.
@ -63,14 +65,20 @@ module.exports = {
context: '.',
manifest: require(path.resolve(__dirname, "./manifest.json"))
}),
new HtmlWebPackPlugin({ title: "webCAD" }),
new HtmlWebPackPlugin(
{
title: "webCAD",
template: 'index.html'
}),
new AddAssetHtmlPlugin({ filepath: path.resolve(__dirname, "./dist/dll.js") }),
new ExtractTextPlugin('styles.css'),
new ExtractTextPlugin({ filename: 'styles.css' }),
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
ReactDOM: 'react-dom',
React: 'react'
React: 'react',
THREE: "three",
Zlib: "zlib"
}),
new webpack.optimize.ModuleConcatenationPlugin()
]

Loading…
Cancel
Save