toolbar/EditorToolbar.jsx

This commit is contained in:
liteng 2019-06-28 12:30:03 +08:00
parent 0fd8c11483
commit a10fd84ebb
2 changed files with 373 additions and 15 deletions

View File

@ -35,8 +35,6 @@ class TwoDMenu extends React.Component {
}
render() {
const { className, style } = this.props;
return <MenuItem title={L_TWO_D}>
<MenuItem title={L_BUTTON} onClick={this.handleAddButton}></MenuItem>
<MenuItem title={L_LABEL} onClick={this.handleAddLabel}></MenuItem>

View File

@ -9,26 +9,386 @@ class EditorToolbar extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
alert('Translate');
this.handleEnterSelectMode = this.handleEnterSelectMode.bind(this);
this.handleEnterTranslateMode = this.handleEnterTranslateMode.bind(this);
this.handleEnterRotateMode = this.handleEnterRotateMode.bind(this);
this.handleEnterScaleMode = this.handleEnterScaleMode.bind(this);
this.handleAddPoint = this.handleAddPoint.bind(this);
this.handleAddLine = this.handleAddLine.bind(this);
this.handleAddPolygon = this.handleAddPolygon.bind(this);
this.handleSpray = this.handleSpray.bind(this);
}
render() {
return <Toolbar className={'EditorToolbar'} direction={'vertical'}>
<IconButton icon={'select'} selected={true} onClick={this.handleClick}></IconButton>
<IconButton icon={'translate'}></IconButton>
<IconButton icon={'rotate'}></IconButton>
<IconButton icon={'scale'}></IconButton>
<IconButton icon={'select'} selected={true} onClick={this.handleEnterSelectMode}></IconButton>
<IconButton icon={'translate'} onClick={this.handleEnterTranslateMode}></IconButton>
<IconButton icon={'rotate'} onClick={this.handleEnterRotateMode}></IconButton>
<IconButton icon={'scale'} onClick={this.handleEnterScaleMode}></IconButton>
<ToolbarSeparator />
<IconButton icon={'point'}></IconButton>
<IconButton icon={'line'}></IconButton>
<IconButton icon={'spray'}></IconButton>
<IconButton icon={'texture'}></IconButton>
<IconButton icon={'point'} onClick={this.handleAddPoint}></IconButton>
<IconButton icon={'line'} onClick={this.handleAddLine}></IconButton>
<IconButton icon={'spray'} onClick={this.handleAddPolygon}></IconButton>
<IconButton icon={'texture'} onClick={this.handleSpray}></IconButton>
</Toolbar>;
}
componentDidMount() {
// app.on(`changeMode.${this.id}`, this.onChangeMode.bind(this));
}
// --------------------------------- -------------------------------------
handleEnterSelectMode() {
app.call('changeMode', this, 'select');
}
// -------------------------------- --------------------------------------
handleEnterTranslateMode() {
app.call('changeMode', this, 'translate');
}
// -------------------------------- ---------------------------------------
handleEnterRotateMode() {
app.call('changeMode', this, 'rotate');
}
// -------------------------------- ---------------------------------------
handleEnterScaleMode() {
app.call('changeMode', this, 'scale');
}
// ------------------------------ -------------------------------------
onChangeMode(mode) {
var selectBtn = UI.get('selectBtn', this.id);
var translateBtn = UI.get('translateBtn', this.id);
var rotateBtn = UI.get('rotateBtn', this.id);
var scaleBtn = UI.get('scaleBtn', this.id);
selectBtn.unselect();
translateBtn.unselect();
rotateBtn.unselect();
scaleBtn.unselect();
switch (mode) {
case 'select':
selectBtn.select();
break;
case 'translate':
translateBtn.select();
break;
case 'rotate':
rotateBtn.select();
break;
case 'scale':
scaleBtn.select();
break;
}
}
// --------------------------------- ------------------------------------------
handleAddPoint() {
this.isAddingPoint = !this.isAddingPoint;
var addPointBtn = UI.get('addPointBtn', this.id);
if (this.isAddingPoint) {
addPointBtn.select();
app.on(`intersect.${this.id}AddPoint`, this.onAddPointIntersect.bind(this));
} else {
addPointBtn.unselect();
app.on(`intersect.${this.id}AddPoint`, null);
}
}
onAddPointIntersect(obj, event) {
if (event.button !== 0) {
return;
}
this.onAddPoint();
var geometry = new THREE.CircleBufferGeometry(0.4, 32, 0, Math.PI * 2);
var material = new THREE.PointsMaterial({
color: 0xffffff * Math.random(),
polygonOffset: true,
polygonOffsetFactor: -40,
});
var mesh = new THREE.Mesh(geometry, material);
mesh.position.copy(obj.point);
var normal = obj.face.normal.clone();
normal.transformDirection(obj.object.matrixWorld);
mesh.lookAt(new THREE.Vector3().addVectors(obj.point, normal));
mesh.name = L_POINT;
app.editor.execute(new AddObjectCommand(mesh));
}
// ---------------------------------- 线 -----------------------------------------
handleAddLine() {
if (this.hasLoadLineScript === undefined) {
this.hasLoadLineScript = true;
app.require('line').then(() => {
this.onAddLine();
});
} else {
this.onAddLine();
}
}
onAddLine() {
this.isAddingLine = !this.isAddingLine;
var addLineBtn = UI.get('addLineBtn', this.id);
if (this.isAddingLine) {
addLineBtn.select();
app.on(`intersect.${this.id}AddLine`, this.onAddLineIntersect.bind(this));
app.on(`dblclick.${this.id}AddLine`, this.onAddLineDblClick.bind(this));
this.linePositions = [];
this.lineColors = [];
var geometry = new THREE.LineGeometry();
var material = new THREE.LineMaterial({
color: 0xffffff,
linewidth: 8, // in pixels
vertexColors: THREE.VertexColors,
dashed: false,
polygonOffset: true,
polygonOffsetFactor: -40,
});
var renderer = app.editor.renderer;
material.resolution.set(renderer.domElement.clientWidth, renderer.domElement.clientHeight);
this.line = new THREE.Line2(geometry, material);
this.line.name = L_LINE;
app.editor.execute(new AddObjectCommand(this.line));
} else {
addLineBtn.unselect();
app.on(`intersect.${this.id}AddLine`, null);
app.on(`dblclick.${this.id}AddLine`, null);
this.linePositions = null;
this.lineColors = null;
this.line = null;
}
}
onAddLineIntersect(obj, event) {
if (event.button !== 0) {
return;
}
this.linePositions.push(obj.point.x, obj.point.y, obj.point.z);
var color = new THREE.Color(0xffffff * Math.random());
this.lineColors.push(color.r, color.g, color.b);
if (this.linePositions.length < 6) {
return;
}
var geometry = this.line.geometry;
geometry.setPositions(this.linePositions);
geometry.setColors(this.lineColors);
geometry.maxInstancedCount = this.linePositions.length / 3 - 1;
this.line.computeLineDistances();
}
onAddLineDblClick(obj) {
this.onAddLine();
}
// ---------------------------------- ------------------------------------------
handleAddPolygon() {
this.isAddingPolygon = !this.isAddingPolygon;
var addPolygonBtn = UI.get('addPolygonBtn', this.id);
if (this.isAddingPolygon) {
addPolygonBtn.select();
app.on(`intersect.${this.id}AddPolygon`, this.onAddPolygonIntersect.bind(this));
app.on(`dblclick.${this.id}AddPolygon`, this.onAddPolygonDblClick.bind(this));
var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(new Float32Array(300), 3));
geometry.addAttribute('normal', new THREE.BufferAttribute(new Float32Array(300), 3));
geometry.addAttribute('uv', new THREE.BufferAttribute(new Float32Array(200), 2));
geometry.attributes.position.count = 0;
geometry.attributes.normal.count = 0;
geometry.attributes.uv.count = 0;
var material = new THREE.MeshBasicMaterial({
color: 0xffffff * Math.random(),
polygonOffset: true,
polygonOffsetFactor: -40,
side: THREE.DoubleSide,
});
this.polygon = new THREE.Mesh(geometry, material);
this.polygon.name = L_POLYGON;
this.polygon.drawMode = THREE.TriangleStripDrawMode;
app.editor.execute(new AddObjectCommand(this.polygon));
this.polygonPoints = [];
} else {
addPolygonBtn.unselect();
app.on(`intersect.${this.id}AddPolygon`, null);
app.on(`dblclick.${this.id}AddPolygon`, null);
this.polygon = null;
this.polygonPoints = null;
}
}
onAddPolygonIntersect(obj) {
if (event.button !== 0) {
return;
}
this.polygonPoints.push(obj.point);
var position = this.polygon.geometry.attributes.position;
var normal = this.polygon.geometry.attributes.normal;
var uv = this.polygon.geometry.attributes.uv;
var index = position.count;
position.setXYZ(
index,
obj.point.x,
obj.point.y,
obj.point.z,
);
normal.setXYZ(index, obj.face.normal.x, obj.face.normal.y, obj.face.normal.z);
uv.setXY(index, obj.uv.x, obj.uv.y);
position.count++;
normal.count++;
uv.count++;
position.needsUpdate = true;
normal.needsUpdate = true;
uv.needsUpdate = true;
}
onAddPolygonDblClick(obj) {
this.onAddPolygon();
}
// -------------------------------- ---------------------------------------
handleSpray() {
this.isSpraying = !this.isSpraying;
var sprayBtn = UI.get('sprayBtn', this.id);
if (this.isSpraying) {
sprayBtn.select();
app.on(`intersect.${this.id}Spray`, this.onSprayIntersect.bind(this));
} else {
sprayBtn.unselect();
app.on(`intersect.${this.id}Spray`, null);
}
}
onSprayIntersect(obj, event) {
if (event.button !== 0) {
return;
}
this.onSpray();
var mesh = obj.object;
var position = obj.point;
if (mesh instanceof THREE.Points) {
return;
}
var normal = obj.face.normal.clone();
normal.transformDirection(obj.object.matrixWorld);
var mat = new THREE.Matrix4();
mat.lookAt(position, new THREE.Vector3().addVectors(position, normal), mesh.up);
var orientation = new THREE.Euler();
orientation.setFromRotationMatrix(mat);
var size = new THREE.Vector3(1, 1, 1).multiplyScalar(10 + Math.random() * 10);
if (this.decalMaterial === undefined) {
var textureLoader = new THREE.TextureLoader();
var decalDiffuse = textureLoader.load('assets/textures/decal/decal-diffuse.png');
var decalNormal = textureLoader.load('assets/textures/decal/decal-normal.jpg');
this.decalMaterial = new THREE.MeshPhongMaterial({
specular: 0x444444,
map: decalDiffuse,
normalMap: decalNormal,
normalScale: new THREE.Vector2(1, 1),
shininess: 30,
transparent: true,
depthTest: true,
depthWrite: false,
polygonOffset: true,
polygonOffsetFactor: -4,
wireframe: false
});
}
var material = this.decalMaterial.clone();
material.color.setHex(Math.random() * 0xffffff);
var decal = new THREE.Mesh(new THREE.DecalGeometry(mesh, position, orientation, size), material);
decal.name = L_DECAL;
app.editor.execute(new AddObjectCommand(decal));
}
// ------------------------------- -------------------------------------
onDig() {
var digBtn = UI.get('digBtn', this.id);
digBtn.select();
if (this.digTool === undefined) {
this.digTool = new DigTool(app);
this.digTool.on(`end.${this.id}`, () => {
digBtn.unselect();
});
}
this.digTool.start();
}
}
export default EditorToolbar;