Commit 9008ee1f authored by amandaghassaei's avatar amandaghassaei

adding in crease stiffness

parent a11b6ce4
......@@ -65,7 +65,7 @@
<script id="zeroTexture" type="x-shader/x-fragment">
void main(){
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
gl_FragColor = vec4(0.0);
}
</script>
......@@ -83,7 +83,7 @@
float isFixed = texture2D(u_mass, scaledFragCoord).y;
if (isFixed == 1.0){
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
gl_FragColor = vec4(0.0);
return;
}
......@@ -113,7 +113,7 @@
vec2 mass = texture2D(u_mass, scaledFragCoord).xy;
if (mass.y == 1.0){
gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
gl_FragColor = vec4(0.0);
return;
}
vec3 force = texture2D(u_externalForces, scaledFragCoord).xyz;
......@@ -153,6 +153,42 @@
}
</script>
<script id="thetaCalcShader" type="x-shader/x-fragment">
precision mediump float;
uniform vec2 u_textureDimFaces;
uniform vec2 u_textureDimCreases;
uniform sampler2D u_normals;
uniform sampler2D u_lastTheta;
uniform sampler2D u_creaseVectors;
void main(){
vec2 fragCoord = gl_FragCoord.xy;
vec2 scaledFragCoord = fragCoord/u_textureDimCreases;
vec4 lastTheta = texture2D(u_lastTheta, scaledFragCoord);
if (lastTheta[2]<0.0){
gl_FragColor = vec4(0.0, 0.0, -1.0, -1.0);
return;
}
vec2 normal1Index = vec2(mod(lastTheta[2], u_textureDimFaces.x)+0.5, floor(lastTheta[2]/u_textureDimFaces.x)+0.5);
normal1Index /= u_textureDimFaces;
vec2 normal2Index = vec2(mod(lastTheta[3], u_textureDimFaces.x)+0.5, floor(lastTheta[3]/u_textureDimFaces.x)+0.5);
normal2Index /= u_textureDimFaces;
vec3 normal1 = texture2D(u_normals, normal1Index).xyz;
vec3 normal2 = texture2D(u_normals, normal2Index).xyz;
float theta = acos(dot(normal1, normal2));//normals are already normalized, no need to divide by length
vec3 creaseVector = texture2D(u_creaseVectors, scaledFragCoord).xyz;
float sign = dot(cross(normal1, normal2), creaseVector);
if (sign < 0.0) theta *= -1.0;
gl_FragColor = vec4(theta, theta-lastTheta[0], lastTheta[2], lastTheta[3]);//[theta, w, normal1Index, normal2Index]
}
</script>
<script type="text/javascript" src="dependencies/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="dependencies/jquery-ui.min.js"></script>
<script type="text/javascript" src="dependencies/flat-ui.min.js"></script>
......@@ -169,6 +205,7 @@
<script type="text/javascript" src="js/globals.js"></script>
<script type="text/javascript" src="js/node.js"></script>
<script type="text/javascript" src="js/beam.js"></script>
<script type="text/javascript" src="js/crease.js"></script>
<script type="text/javascript" src="js/model.js"></script>
<script type="text/javascript" src="js/dynamicModel.js"></script>
......@@ -214,6 +251,12 @@
</div>
<div id="controls">
<a href="#" id="about" class="btn btn-lg btn-default">About</a><br/><br/>
<div class="sliderInput" id="creaseAngle">
<span class="label-slider">Crease Angle : </span><div class="flat-slider ui-slider ui-corner-all ui-slider-horizontal ui-widget ui-widget-content"></div>
<input value="" placeholder="" class="form-control int" type="text">
</div>
<br/><br/><br/>
<div class="sliderInput" id="axialStiffness">
<span class="label-slider">Axial Stiffness : </span><div class="flat-slider ui-slider ui-corner-all ui-slider-horizontal ui-widget ui-widget-content"></div>
<input value="" placeholder="" class="form-control int" type="text">
......
......@@ -56,6 +56,10 @@ function initControls(globals){
globals.dynamicModel.reset();
});
setSliderInput("#creaseAngle", globals.creaseAngle, 0, Math.PI, 0.1, function(val){
globals.creaseAngle = val;
});
function setDeltaT(val){
$("#deltaT").html(val.toFixed(4));
}
......
/**
* Created by amandaghassaei on 2/25/17.
*/
function Crease(edge, face1Index, face2Index, targetTheta, node1, node2){
//face1 corresponds to node1, face2 to node2
this.edge = edge;
this.face1Index = face1Index;
this.face2Index = face2Index;
this.targetTheta = targetTheta;
this.node1 = node1;
this.node2 = node2;
node1.addCrease(this);
node2.addCrease(this);
}
Crease.prototype.getLength = function(){
return this.edge.getLength();
};
Crease.prototype.getVector = function(){
return this.edge.getVector();
};
Crease.prototype.getNormal1Index = function(){
return this.face1Index;
};
Crease.prototype.getNormal2Index = function(){
return this.face2Index;
};
Crease.prototype.destroy = function(){
this.node1.removeCrease(this);
this.node2.removeCrease(this);
this.edge = null;
this.face1Index = null;
this.face2Index = null;
this.targetTheta = null;
this.node1 = null;
this.node2 = null;
};
\ No newline at end of file
......@@ -4,12 +4,15 @@
function initDynamicModel(globals){
var object3D = new THREE.Object3D();
var geometry = new THREE.Geometry();
geometry.dynamic = true;
var object3D = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial({shading: THREE.FlatShading, side: THREE.DoubleSide}));
object3D.visible = globals.dynamicSimVisible;
globals.threeView.sceneAddModel(object3D);
var nodes;
var edges;
var creases;
var originalPosition;
var position;
......@@ -18,14 +21,31 @@ function initDynamicModel(globals){
var lastVelocity;
var externalForces;
var mass;
var meta;//[beamsIndex, numBeams]
var meta;//[beamsIndex, numBeams, creasesIndex, numCreases]
var beamMeta;//[K, D, length, otherNodeIndex]
var normals;
var creaseMeta;//[k, d, targetTheta, length (to node)]
var creaseVectors;//vectors of oriented edges in crease
var theta;//[theta, w, normalIndex1, normalIndex2]
var lastTheta;//[theta, w, normalIndex1, normalIndex2]
function syncNodesAndEdges(){
nodes = globals.model.getNodes();
edges = globals.model.getEdges();
//update mesh nodes
geometry.vertices = [];
for (var i=0;i<nodes.length;i++){
geometry.vertices.push(nodes[i].getPosition());
}
geometry.faces = [];
geometry.faces.push(new THREE.Face3(0,1,2));
geometry.faces.push(new THREE.Face3(0,2,3));
geometry.computeFaceNormals();
creases = globals.model.getCreases();
initTypedArrays();
}
......@@ -34,6 +54,8 @@ function initDynamicModel(globals){
var textureDim = 0;
var textureDimEdges = 0;
var textureDimFaces = 0;
var textureDimCreases = 0;
syncNodesAndEdges();
initTexturesAndPrograms(globals.gpuMath);
steps = parseInt(setSolveParams());
......@@ -44,6 +66,11 @@ function initDynamicModel(globals){
globals.gpuMath.step("zeroTexture", [], "u_lastPosition");
globals.gpuMath.step("zeroTexture", [], "u_velocity");
globals.gpuMath.step("zeroTexture", [], "u_lastVelocity");
// for (var i=0;i<creases.length;i++){
// lastTheta[i*4] = 0;
// lastTheta[i*4+1] = 0;
// }
}
function runSolver(){
......@@ -86,26 +113,51 @@ function initDynamicModel(globals){
var gpuMath = globals.gpuMath;
gpuMath.setProgram("thetaCalc");
gpuMath.setSize(textureDimCreases, textureDimCreases);
gpuMath.step("thetaCalc", ["u_normals", "u_lastTheta", "u_creaseVectors"], "u_theta");
gpuMath.step("velocityCalc", ["u_lastPosition", "u_lastVelocity", "u_originalPosition", "u_externalForces",
"u_mass", "u_meta", "u_beamMeta"], "u_velocity");
gpuMath.step("positionCalc", ["u_velocity", "u_lastPosition", "u_mass"], "u_position");
gpuMath.swapTextures("u_theta", "u_lastTheta");
gpuMath.swapTextures("u_velocity", "u_lastVelocity");
gpuMath.swapTextures("u_position", "u_lastPosition");
}
function render(){
var vectorLength = 1;
globals.gpuMath.setProgram("packToBytes");
globals.gpuMath.setUniformForProgram("packToBytes", "u_vectorLength", vectorLength, "1f");
globals.gpuMath.setSize(textureDim*vectorLength, textureDim);
globals.gpuMath.step("packToBytes", ["u_theta"], "outputBytes");
if (globals.gpuMath.readyToRead()) {
var numPixels = creases.length*vectorLength;
var height = Math.ceil(numPixels/(textureDimCreases*vectorLength));
var pixels = new Uint8Array(height*textureDimCreases*4*vectorLength);
globals.gpuMath.readPixels(0, 0, textureDimCreases * vectorLength, height, pixels);
var parsedPixels = new Float32Array(pixels.buffer);
for (var i = 0; i < creases.length; i++) {
console.log(parsedPixels[i])
}
} else {
console.log("here");
}
var vectorLength = 3;
globals.gpuMath.setProgram("packToBytes");
globals.gpuMath.setUniformForProgram("packToBytes", "u_vectorLength", vectorLength, "1f");
globals.gpuMath.setSize(textureDim*vectorLength, textureDim);
globals.gpuMath.step("packToBytes", ["u_lastPosition"], "outputBytes");
var pixels = new Uint8Array(textureDim*textureDim*4*vectorLength);
if (globals.gpuMath.readyToRead()) {
var numPixels = nodes.length*vectorLength;
var height = Math.ceil(numPixels/(textureDim*vectorLength));
var pixels = new Uint8Array(height*textureDim*4*vectorLength);//todo only grab pixels you need
globals.gpuMath.readPixels(0, 0, textureDim * vectorLength, height, pixels);
var parsedPixels = new Float32Array(pixels.buffer);
for (var i = 0; i < nodes.length; i++) {
......@@ -116,6 +168,9 @@ function initDynamicModel(globals){
for (var i=0;i<edges.length;i++){
edges[i].render();
}
geometry.verticesNeedUpdate = true;
geometry.computeFaceNormals();
updateNormals();
} else {
console.log("here");
}
......@@ -163,6 +218,10 @@ function initDynamicModel(globals){
gpuMath.initFrameBufferForTexture("u_velocity");
gpuMath.initTextureFromData("u_lastVelocity", textureDim, textureDim, "FLOAT", lastVelocity);
gpuMath.initFrameBufferForTexture("u_lastVelocity");
gpuMath.initTextureFromData("u_theta", textureDimCreases, textureDimCreases, "FLOAT", theta);
gpuMath.initFrameBufferForTexture("u_theta");
gpuMath.initTextureFromData("u_lastTheta", textureDimCreases, textureDimCreases, "FLOAT", lastTheta);
gpuMath.initFrameBufferForTexture("u_lastTheta");
gpuMath.initTextureFromData("u_originalPosition", textureDim, textureDim, "FLOAT", originalPosition);
gpuMath.initTextureFromData("u_meta", textureDim, textureDim, "FLOAT", meta);
......@@ -184,6 +243,13 @@ function initDynamicModel(globals){
gpuMath.setUniformForProgram("velocityCalc", "u_textureDim", [textureDim, textureDim], "2f");
gpuMath.setUniformForProgram("velocityCalc", "u_textureDimEdges", [textureDimEdges, textureDimEdges], "2f");
gpuMath.createProgram("thetaCalc", vertexShader, document.getElementById("thetaCalcShader").text);
gpuMath.setUniformForProgram("thetaCalc", "u_normals", 0, "1i");
gpuMath.setUniformForProgram("thetaCalc", "u_lastTheta", 1, "1i");
gpuMath.setUniformForProgram("thetaCalc", "u_creaseVectors", 2, "1i");
gpuMath.setUniformForProgram("thetaCalc", "u_textureDimFaces", [textureDimFaces, textureDimFaces], "2f");
gpuMath.setUniformForProgram("thetaCalc", "u_textureDimCreases", [textureDimCreases, textureDimCreases], "2f");
gpuMath.createProgram("packToBytes", vertexShader, document.getElementById("packToBytesShader").text);
gpuMath.initTextureFromData("outputBytes", textureDim*4, textureDim, "UNSIGNED_BYTE", null);
gpuMath.initFrameBufferForTexture("outputBytes");
......@@ -207,17 +273,21 @@ function initDynamicModel(globals){
return 0;
}
function updateMaterials(shouldUpdateLength){
function updateMaterials(initing){
var index = 0;
for (var i=0;i<nodes.length;i++){
meta[4*i] = index;
meta[4*i+1] = nodes[i].numBeams();
if (initing) {
meta[4*i] = index;
meta[4*i+1] = nodes[i].numBeams();
}
for (var j=0;j<nodes[i].beams.length;j++){
var beam = nodes[i].beams[j];
beamMeta[4*index] = beam.getK();
beamMeta[4*index+1] = beam.getD();
if (shouldUpdateLength) beamMeta[4*index+2] = beam.getLength();
beamMeta[4*index+3] = beam.getOtherNode(nodes[i]).getIndex();
if (initing) {
beamMeta[4*index+2] = beam.getLength();
beamMeta[4*index+3] = beam.getOtherNode(nodes[i]).getIndex();
}
index+=1;
}
}
......@@ -253,6 +323,28 @@ function initDynamicModel(globals){
globals.gpuMath.initTextureFromData("u_originalPosition", textureDim, textureDim, "FLOAT", originalPosition, true);
}
function updateNormals(){
var numFaces = geometry.faces.length;
for (var i=0;i<numFaces;i++){
var normal = geometry.faces[i].normal;
normals[i*4] = normal.x;
normals[i*4+1] = normal.y;
normals[i*4+2] = normal.z;
}
globals.gpuMath.initTextureFromData("u_normals", textureDimFaces, textureDimFaces, "FLOAT", normals, true);
}
function updateCreaseVectors(){
for (var i=0;i<creases.length;i++){
var rgbaIndex = i*4;
var vector = creases[i].getVector();
creaseVectors[rgbaIndex] = vector.x;
creaseVectors[rgbaIndex+1] = vector.y;
creaseVectors[rgbaIndex+2] = vector.z;
}
globals.gpuMath.initTextureFromData("u_creaseVectors", textureDimCreases, textureDimCreases, "FLOAT", creaseVectors, true);
}
function initTypedArrays(){
textureDim = calcTextureSize(nodes.length);
......@@ -263,6 +355,12 @@ function initDynamicModel(globals){
}
textureDimEdges = calcTextureSize(numEdges);
var numFaces = geometry.faces.length;
textureDimFaces = calcTextureSize(numFaces);
var numCreases = creases.length;
textureDimCreases = calcTextureSize(numCreases);
originalPosition = new Float32Array(textureDim*textureDim*4);
position = new Float32Array(textureDim*textureDim*4);
lastPosition = new Float32Array(textureDim*textureDim*4);
......@@ -273,6 +371,12 @@ function initDynamicModel(globals){
meta = new Float32Array(textureDim*textureDim*4);
beamMeta = new Float32Array(textureDimEdges*textureDimEdges*4);
normals = new Float32Array(textureDimFaces*textureDimFaces*4);
creaseMeta = new Float32Array(textureDimCreases*textureDimCreases*4);
creaseVectors = new Float32Array(textureDimCreases*textureDimCreases*4);
theta = new Float32Array(textureDimCreases*textureDimCreases*4);
lastTheta = new Float32Array(textureDimCreases*textureDimCreases*4);
for (var i=0;i<textureDim*textureDim;i++){
mass[4*i+1] = 1;//set all fixed by default
}
......@@ -281,19 +385,26 @@ function initDynamicModel(globals){
mass[4*index] = node.getSimMass();
});
for (var i=0;i<textureDimCreases*textureDimCreases;i++){
if (i >= numCreases){
lastTheta[i*4+2] = -1;
lastTheta[i*4+3] = -1;
continue;
}
lastTheta[i*4+2] = creases[i].getNormal1Index();
lastTheta[i*4+3] = creases[i].getNormal2Index();
}
updateCreaseVectors();
updateNormals();
updateOriginalPosition();
updateMaterials(true);
updateFixed();
updateExternalForces();
}
function getChildren(){
return object3D.children;
}
return {
setVisibility: setVisibility,
getChildren: getChildren,
setViewMode: setViewMode,
syncNodesAndEdges: syncNodesAndEdges,
updateOriginalPosition: updateOriginalPosition,
......
......@@ -19,6 +19,7 @@ function initGlobals(){
schematicVisible: true,
//sim settings
creaseAngle: 0,
axialStiffness: 100,
creaseStiffness: 1,
panelStiffness: 1,
......
......@@ -21,6 +21,9 @@ function initModel(globals){
edges.push(new Beam([nodes[3], nodes[0]]));
edges.push(new Beam([nodes[3], nodes[2]]));
var creases = [];
creases.push(new Crease(edges[1], 1, 0, 0, nodes[1], nodes[0]));
_.each(nodes, function(node){
globals.threeView.sceneAddModel(node.getObject3D());
});
......@@ -36,8 +39,13 @@ function initModel(globals){
return edges;
}
function getCreases(){
return creases;
}
return {
getNodes: getNodes,
getEdges: getEdges
getEdges: getEdges,
getCreases: getCreases
}
}
\ No newline at end of file
......@@ -22,6 +22,7 @@ function Node(position, index){
this.object3D._myNode = this;
this.beams = [];
this.creases = [];
this.externalForce = null;
this.fixed = false;
......@@ -78,6 +79,16 @@ Node.prototype.getMass = function(){
Node.prototype.addCrease = function(crease){
this.creases.push(crease);
};
Node.prototype.removeCrease = function(crease){
if (this.creases === null) return;
var index = this.creases.indexOf(crease);
if (index>=0) this.creases.splice(index, 1);
};
Node.prototype.addBeam = function(beam){
this.beams.push(beam);
......@@ -163,5 +174,6 @@ Node.prototype.destroy = function(){
this.object3D._myNode = null;
this.object3D = null;
this.beams = null;
this.creases = null;
this.externalForce = null;
};
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment