Skip to content
Snippets Groups Projects
DmaCell.js 10 KiB
Newer Older
Amanda Ghassaei's avatar
Amanda Ghassaei committed
/**
 * Created by aghassaei on 1/14/15.
 */


//a Cell, a unit piece of the lattice

Amanda Ghassaei's avatar
Amanda Ghassaei committed
var cellMaterials = [new THREE.MeshNormalMaterial(),
        new THREE.MeshBasicMaterial({color:0x000000, wireframe:true})];

function DMACell(indices, scale, cellMode, partType) {
Amanda Ghassaei's avatar
Amanda Ghassaei committed

    this.indices = indices;
Amanda Ghassaei's avatar
Amanda Ghassaei committed

    this.cellMesh = this._buildCellMesh();
    this._doMeshTransformations(this.cellMesh);//some cell types require transformations
    dmaGlobals.three.sceneAdd(this.cellMesh,this._sceneType(indices));

    this.draw(scale, cellMode, partType);
Amanda Ghassaei's avatar
Amanda Ghassaei committed

    this.hideForStockSimulation = false;
DMACell.prototype._sceneType = function(indices){
    if (!indices || indices == null || indices === undefined) return null;
    return "cell";
};

DMACell.prototype.draw = function(scale, cellMode, partType){
    if (this.hideForStockSimulation) return;
    if (!scale) scale = dmaGlobals.lattice.get("scale");
    if (!cellMode) cellMode = dmaGlobals.appState.get("cellMode");
    if (!partType)  partType = dmaGlobals.lattice.get("partType");
amandaghassaei's avatar
amandaghassaei committed
    //var beamMode = partType == "beam";
    var beamMode = false;
    var partMode = cellMode == "part";

    //init parts/beams if needed
    if (partMode &&!beamMode && !this.parts) this.parts = this._initParts();
    if (beamMode && !this.beams) {
        this.nodes = this._initNodes(this.cellMesh.children[0].geometry.vertices);
        this.beams = this._initBeams(this.nodes, this.cellMesh.children[0].geometry.faces);
    }

    //update scale
    this.updateForScale(scale, cellMode, partType);

    //set visibility
amandaghassaei's avatar
amandaghassaei committed
    this._setCellMeshVisibility(!partMode);
    _.each(this.parts, function(part){
amandaghassaei's avatar
amandaghassaei committed
        if (part) part.setVisibility(partMode && !beamMode);
Amanda Ghassaei's avatar
Amanda Ghassaei committed
    });
    _.each(this.beams, function(beam){
amandaghassaei's avatar
amandaghassaei committed
        beam.setVisibility(beamMode && partMode);
DMACell.prototype.hide = function(){//only used in the context of stock simulation
    this._setCellMeshVisibility(false);
    _.each(this.parts, function(part){
        if (part) part.setVisibility(false);
    });
    _.each(this.beams, function(beam){
        beam.setVisibility(false);
    });
};

Amanda Ghassaei's avatar
Amanda Ghassaei committed
///////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////SCALE/POSITION////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////

DMACell.prototype.updateForScale = function(scale, cellMode, partType){
    if (!scale) scale = dmaGlobals.lattice.get("scale");
    var position = this._calcPosition();
Amanda Ghassaei's avatar
Amanda Ghassaei committed
    this._setMeshPosition(this.cellMesh, position);
    this.cellMesh.scale.set(scale, scale, scale);//must do this so highlighting works properly in part mode
    //only update visible object to scale
amandaghassaei's avatar
amandaghassaei committed
    if (!cellMode) cellMode = dmaGlobals.appState.get("cellMode");
    if (!partType)  partType = dmaGlobals.lattice.get("partType");
Amanda Ghassaei's avatar
Amanda Ghassaei committed
    if (cellMode == "part"){
        if (partType == "beam"){
            _.each(this.beams, function(beam){
                if (beam) beam.updateForScale(scale, position);//todo this is not working quite right yet
            });
        } else {
            _.each(this.parts, function(part){
                if (part) part.updateForScale(scale, position);
            });
        }
Amanda Ghassaei's avatar
Amanda Ghassaei committed
DMACell.prototype._setMeshPosition = function(mesh, position){
    mesh.position.x = position.x;
    mesh.position.y = position.y;
    mesh.position.z = position.z;
};

DMACell.prototype.moveTo = function(position, axis){//used for stock simulations
    this.cellMesh.position[axis] = position;
    if (dmaGlobals.appState.get("cellMode") == "part"){
        _.each(this.parts, function(part){
            if (part) part.moveTo(position, axis);
        });
    }
DMACell.prototype.getType = function(){
    return null;//only used in freeform layout
Amanda Ghassaei's avatar
Amanda Ghassaei committed
DMACell.prototype.getScale = function(){//need for part relay
Amanda Ghassaei's avatar
Amanda Ghassaei committed
    return dmaGlobals.lattice.get("scale");
DMACell.prototype.getPosition = function(){
    return this.cellMesh.position.clone();
};

DMACell.prototype.getOrientation = function(){
    return this.cellMesh.quaternion.clone();
Amanda Ghassaei's avatar
Amanda Ghassaei committed
DMACell.prototype.getEulerRotation = function(){
    return this.cellMesh.rotation.clone();
};

DMACell.prototype._calcPosition = function(){//need for part relay
    if (this.indices) return dmaGlobals.lattice.getPositionForIndex(this.indices);
    return this.cellMesh.position;//used for cam simulation
Amanda Ghassaei's avatar
Amanda Ghassaei committed
DMACell.prototype._setCellMeshVisibility = function(visibility){
    this.cellMesh.visible = visibility;
};

Amanda Ghassaei's avatar
Amanda Ghassaei committed
DMACell.prototype.xScale = function(scale){
    return dmaGlobals.lattice.xScale(scale);
};

DMACell.prototype.yScale = function(scale){
    return dmaGlobals.lattice.yScale(scale);
};

DMACell.prototype.zScale = function(scale){
    return dmaGlobals.lattice.zScale(scale);
};


Amanda Ghassaei's avatar
Amanda Ghassaei committed
///////////////////////////////////////////////////////////////////////////////////////////////
Amanda Ghassaei's avatar
Amanda Ghassaei committed
/////////////////////////////////META//////////////////////////////////////////////////////////
Amanda Ghassaei's avatar
Amanda Ghassaei committed
///////////////////////////////////////////////////////////////////////////////////////////////

amandaghassaei's avatar
amandaghassaei committed
DMACell.prototype._buildCellMesh = function(material){//called from every subclass
    var unitCellGeo = this._getGeometry();
    if (!material) material = cellMaterials;
    var mesh = THREE.SceneUtils.createMultiMaterialObject(unitCellGeo, material);
    mesh.myParent = this;//we need a reference to this instance from the mesh for intersection selection stuff
    return mesh;
};

DMACell.prototype._doMeshTransformations = function(mesh){};//by default, no mesh transformations

DMACell.prototype._initParts = function(){
Amanda Ghassaei's avatar
Amanda Ghassaei committed
    return [];//override in subclasses
amandaghassaei's avatar
amandaghassaei committed
DMACell.prototype.removePart = function(index){
    this.parts[index].destroy();
    this.parts[index] = null;
    var hasAnyParts = false;//check if all parts have been deleted
    _.each(this.parts, function(part){
        if (part) hasAnyParts = true;
    });
    if (!hasAnyParts) dmaGlobals.lattice.removeCell(this);//if all parts are gone, remove cell
};

DMACell.prototype.destroyParts = function(){
    _.each(this.parts, function(part){
        if (part) part.destroy();
    });
    this.parts = null;
};

Amanda Ghassaei's avatar
Amanda Ghassaei committed
DMACell.prototype._initNodes = function(vertices){
    var position = this.getPosition();
    var orientation = this.getOrientation();
    var nodes = [];
Amanda Ghassaei's avatar
Amanda Ghassaei committed
    var scale = this.getScale();
Amanda Ghassaei's avatar
Amanda Ghassaei committed
    for (var i=0;i<vertices.length;i++){
Amanda Ghassaei's avatar
Amanda Ghassaei committed
        var vertex = vertices[i].clone();
Amanda Ghassaei's avatar
Amanda Ghassaei committed
        vertex.applyQuaternion(orientation);
        vertex.add(position);
amandaghassaei's avatar
amandaghassaei committed
        //vertex.multiplyScalar(scale);
Amanda Ghassaei's avatar
Amanda Ghassaei committed
        nodes.push(new DmaNode(vertex, i));
    }
    return nodes;
};

Amanda Ghassaei's avatar
Amanda Ghassaei committed
DMACell.prototype._initBeams = function(nodes, faces){
    var beams = [];
    var self = this;
    var addBeamFunc = function(index1, index2){
        var duplicate = false;
        _.each(beams, function(beam){
            var index = beam.getIndex();
            if (index[0] == index1 && index[1] == index2) duplicate = true;
        });
        if (duplicate) return;
        var diff = nodes[index1].getPosition();
        diff.sub(nodes[index2].getPosition());
        if (diff.length() > self.getScale()*1.01) return;
        if (index2>index1) {
            beams.push(new DmaBeam(nodes[index1], nodes[index2], self));
        }
    };
    for (var i=0;i<nodes.length;i++){
        _.each(faces, function(face){
            if (face.a == i) {
                addBeamFunc(i, face.b);
                addBeamFunc(i, face.c);
            } else if (face.b == i){
                addBeamFunc(i, face.a);
                addBeamFunc(i, face.c);
            } else if (face.c == i){
                addBeamFunc(i, face.a);
                addBeamFunc(i, face.b);
            }
        })
    }
    return beams;
Amanda Ghassaei's avatar
Amanda Ghassaei committed
DMACell.prototype.destroy = function(){
    if (this.cellMesh) {
        dmaGlobals.three.sceneRemove(this.cellMesh, this._sceneType(this.indices));
        this.cellMesh.myParent = null;
Amanda Ghassaei's avatar
Amanda Ghassaei committed
//            this.cellMesh.dispose();
//            geometry.dispose();
//            material.dispose();
        this.cellMesh = null;
    }
    this.destroyParts();
Amanda Ghassaei's avatar
Amanda Ghassaei committed
    this.indices = null;
Amanda Ghassaei's avatar
Amanda Ghassaei committed
    this.nodes = null;
    this.beams = null;
Amanda Ghassaei's avatar
Amanda Ghassaei committed
DMACell.prototype.toJSON = function(){
    var data = {
        indices:this.indices//todo get rid of this and calculate from min and max
Amanda Ghassaei's avatar
Amanda Ghassaei committed
    };
    if (this.parts) data.parts = this.parts;
    return data;
Amanda Ghassaei's avatar
Amanda Ghassaei committed
};

Amanda Ghassaei's avatar
Amanda Ghassaei committed
///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////FREEFORM SUPERCLASS////////////////////////////////////////////////////
Amanda Ghassaei's avatar
Amanda Ghassaei committed
///////////////////////////////////////////////////////////////////////////////////////////////

function DMAFreeFormCell(indices, scale, parentCellPos, parentCellQuat, direction, parentType){//no rigid lattice structure for cells
    this.parentPos = parentCellPos;
    this.parentQuaternion = parentCellQuat;
    this.parentDirection = direction;
    this.parentType = parentType;
    DMACell.call(this, indices, scale);
}
DMAFreeFormCell.prototype = Object.create(DMACell.prototype);

amandaghassaei's avatar
amandaghassaei committed
DMAFreeFormCell.prototype._calcPosition = function(){//todo this might not be necessary - put in lattice
    var position = {};
amandaghassaei's avatar
amandaghassaei committed
    var zScale = dmaGlobals.lattice.zScale();
    position.x = this.parentPos.x+this.parentDirection.x*zScale/2;
    position.y = this.parentPos.y+this.parentDirection.y*zScale/2;
    position.z = this.parentPos.z+this.parentDirection.z*zScale/2;
    return position;
};
Amanda Ghassaei's avatar
Amanda Ghassaei committed

DMAFreeFormCell.prototype.calcHighlighterPosition = function(face){
    var direction = face.normal.clone();
    direction.applyQuaternion(this.cellMesh.quaternion);
    var position = this.getPosition();
    position.add(direction.clone().multiplyScalar(this.zScale()/2));
    return {index: _.clone(this.indices), direction:direction, position:position};
};

DMAFreeFormCell.prototype.toJSON = function(){
    var json = DMACell.prototype.toJSON.call(this);
    _.extend(json, {
        parentPosition: this.parentPos,
        parentOrientation: this.parentQuaternion,
        direction: this.parentDirection,
        parentType: this.parentType,
        type: this.getType()
    });
    return json;
Amanda Ghassaei's avatar
Amanda Ghassaei committed
};