Last active
August 30, 2018 12:51
-
-
Save KeanW/263f254cb0701fdf67e5b60029565638 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <reference path='../../types/three.d.ts' /> | |
import { Logger } from '../../core/Logger'; | |
let logger = Logger.getInstance(); | |
import { ShowableExtension } from '../../core/ShowableExtension'; | |
export class SkeletonExtension extends ShowableExtension { | |
private _lineMaterial: any = null; | |
private _vertexMaterial: any = null; | |
private _overlayScene = "DasherSkeletonOverlay"; | |
private _toRemove: THREE.Object3D[]; | |
constructor(viewer: Autodesk.Viewing.Private.GuiViewer3D, options: any) { | |
super(viewer, options); | |
this._toRemove = []; | |
} | |
public load(): boolean { | |
logger.log('SkeletonExtension loaded'); | |
this.createUI( | |
'toolbar-sensor-skeleton', | |
'Skeletons', | |
'DasherControlSensors', | |
'grain' | |
); | |
return true; | |
} | |
public unload(): boolean { | |
this.destroyUI('DasherControlSensors'); | |
logger.log('SkeletonExtension unloaded'); | |
return true; | |
} | |
public show(): boolean { | |
this.viewer.addEventListener( | |
Autodesk.Viewing.SELECTION_CHANGED_EVENT, | |
this.onSelectionChanged); | |
this._vertexMaterial = this.createVertexMaterial(); | |
this._lineMaterial = this.createLineMaterial(); | |
this._toRemove = []; | |
this.viewer.impl.createOverlayScene(this._overlayScene); | |
this.viewer.getSelection().forEach(fragId => { | |
this.drawMeshData(fragId); | |
}); | |
return true; | |
} | |
public hide(): boolean { | |
this.viewer.removeEventListener( | |
Autodesk.Viewing.SELECTION_CHANGED_EVENT, | |
this.onSelectionChanged); | |
this._vertexMaterial = null; | |
this._lineMaterial = null; | |
this.clearAdditional(); | |
this.viewer.impl.removeOverlayScene(this._overlayScene); | |
return true; | |
} | |
private addToScene(obj: THREE.Object3D) { | |
// this.viewer.impl.scene.add(obj); | |
// this.viewer.impl.invalidate(true, true, false); | |
this.viewer.impl.addOverlay(this._overlayScene, obj); | |
this.viewer.impl.invalidate(false, false, true); | |
this._toRemove.push(obj); | |
} | |
private removeFromScene(obj: THREE.Object3D) { | |
// this.viewer.impl.scene.remove(obj); | |
// this.viewer.impl.invalidate(true, true, false); | |
this.viewer.impl.removeOverlay(this._overlayScene, obj); | |
this.viewer.impl.invalidate(false, false, true); | |
} | |
private clearAdditional() { | |
// Clear previous geometry | |
for(let obj of this._toRemove) { | |
this.removeFromScene(obj); | |
} | |
this._toRemove = []; | |
} | |
private createVertexMaterial() { | |
let material = new THREE.MeshPhongMaterial({ color: 0xff0000 }); | |
this.viewer.impl.matman().addMaterial( | |
'dasher-material-vertex', | |
material, | |
true); | |
return material; | |
} | |
private createLineMaterial() { | |
let material = new THREE.MeshBasicMaterial( { color: 0x00ff00 }); | |
this.viewer.impl.matman().addMaterial( | |
'dasher-material-line', | |
material, | |
true); | |
return material; | |
} | |
private onSelectionChanged = (event) => { | |
this.clearAdditional(); | |
event.fragIdsArray.forEach(fragId => { | |
this.drawMeshData(fragId); | |
}); | |
} | |
private drawMeshData(fragId) { | |
let fragProxy = this.viewer.impl.getFragmentProxy( | |
this.viewer.model, | |
fragId); | |
let renderProxy = this.viewer.impl.getRenderProxy( | |
this.viewer.model, | |
fragId); | |
fragProxy.getAnimTransform(); | |
let matrix = renderProxy.matrixWorld; | |
let geometry = renderProxy.geometry; | |
let attributes = geometry.attributes; | |
let vA = new THREE.Vector3(); | |
let vB = new THREE.Vector3(); | |
let vC = new THREE.Vector3(); | |
if (attributes.index !== undefined) { | |
let indices = attributes.index.array || geometry.ib; | |
let positions = geometry.vb ? geometry.vb : attributes.position.array; | |
let stride = geometry.vb ? geometry.vbstride : 3; | |
let offsets = geometry.offsets; | |
if (!offsets || offsets.length === 0) { | |
offsets = [{start: 0, count: indices.length, index: 0}]; | |
} | |
for (let oi = 0, ol = offsets.length; oi < ol; ++oi) { | |
let start = offsets[oi].start; | |
let count = offsets[oi].count; | |
let index = offsets[oi].index; | |
for (let i = start, il = start + count; i < il; i += 3) { | |
let a = index + indices[i]; | |
let b = index + indices[i + 1]; | |
let c = index + indices[i + 2]; | |
vA.fromArray(positions, a * stride); | |
vB.fromArray(positions, b * stride); | |
vC.fromArray(positions, c * stride); | |
vA.applyMatrix4(matrix); | |
vB.applyMatrix4(matrix); | |
vC.applyMatrix4(matrix); | |
const w = 0.5; | |
const w2 = w / 2; | |
this.drawVertex (vA, w); | |
this.drawVertex (vB, w); | |
this.drawVertex (vC, w); | |
this.drawLine(vA, vB, w2); | |
this.drawLine(vB, vC, w2); | |
this.drawLine(vC, vA, w2); | |
} | |
} | |
} | |
else { | |
let positions = geometry.vb ? geometry.vb : attributes.position.array; | |
let stride = geometry.vb ? geometry.vbstride : 3; | |
for (let i = 0, j = 0, il = positions.length; i < il; i += 3, j += 9) { | |
let a = i; | |
let b = i + 1; | |
let c = i + 2; | |
vA.fromArray(positions, a * stride); | |
vB.fromArray(positions, b * stride); | |
vC.fromArray(positions, c * stride); | |
vA.applyMatrix4(matrix); | |
vB.applyMatrix4(matrix); | |
vC.applyMatrix4(matrix); | |
const w = 0.5; | |
const w2 = w / 2; | |
this.drawVertex (vA, w); | |
this.drawVertex (vB, w); | |
this.drawVertex (vC, w); | |
this.drawLine(vA, vB, w2); | |
this.drawLine(vB, vC, w2); | |
this.drawLine(vC, vA, w2); | |
} | |
} | |
} | |
private geometryBetween(pointX, pointY, width): [THREE.Geometry, THREE.Matrix4] { | |
let direction = new THREE.Vector3().subVectors(pointY, pointX); | |
let orientation = new THREE.Matrix4(); | |
orientation.lookAt(pointX, pointY, new THREE.Object3D().up); | |
orientation.multiply(new THREE.Matrix4().set( | |
1, 0, 0, 0, | |
0, 0, 1, 0, | |
0, -1, 0, 0, | |
0, 0, 0, 1)); | |
let length = direction.length(); | |
// let edgeGeometry = new THREE.BoxGeometry(width, length, width, 1, 1, 1); | |
let edgeGeometry = new THREE.CylinderGeometry(width, width, length, 8, 1); | |
let translate = new THREE.Matrix4().makeTranslation((pointY.x + pointX.x) / 2, (pointY.y + pointX.y) / 2, (pointY.z + pointX.z) / 2); | |
return [edgeGeometry, translate.multiply(orientation)]; | |
} | |
private drawLine(pointX, pointY, radius) { | |
let geom = this.geometryBetween(pointX, pointY, radius); | |
let edge = new THREE.Mesh(geom[0], this._lineMaterial); | |
edge.applyMatrix(geom[1]); | |
this.addToScene(edge); | |
return edge; | |
} | |
private drawVertex (v, radius) { | |
let vertex = new THREE.Mesh(new THREE.SphereGeometry(radius, 20), this._vertexMaterial); | |
vertex.position.set(v.x, v.y, v.z); | |
this.addToScene(vertex); | |
return vertex; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment