Skip to content

Instantly share code, notes, and snippets.

@KeanW
Last active August 30, 2018 12:51
Show Gist options
  • Save KeanW/263f254cb0701fdf67e5b60029565638 to your computer and use it in GitHub Desktop.
Save KeanW/263f254cb0701fdf67e5b60029565638 to your computer and use it in GitHub Desktop.
/// <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