Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Amira Abdel-Rahman
// (c) Massachusetts Institute of Technology 2019
function initialize(setup){
var voxCount = setup.nodes.length;
for(var i=0;i<voxCount;i++){
setup.nodes[i].currPosition=new THREE.Vector3(setup.nodes[i].position.x,setup.nodes[i].position.y,setup.nodes[i].position.z);
}
}
function doTimeStep(setup,dt){
var voxCount = setup.nodes.length;
for(var i=0;i<voxCount;i++){
timeStep(dt,setup.nodes[i]);
}
}
function timeStep(dt,node){
// var previousDt = dt;
// var linMom=node.linMom.clone();
// var angMom=node.angMom.clone();
// var orient=node.orient.clone();
// var pos=new THREE.Vector3(node.currPosition.x,node.currPosition.y,node.currPosition.z);
var massInverse=1.0;//todo ?? later change
//Translation
var curForce = force(node);
// Calculate acceleration ( F = ma )
var A = curForce.clone().multiplyScalar(massInverse);
// Integrate to get velocity
node.velocity.add(A.clone().multiplyScalar(dt));
// Integrate to get position
node.currPosition.add(node.velocity.clone().multiplyScalar(dt));
//var fricForce = curForce.clone();
//if (isFloorEnabled()) floorForce(dt, &curForce); //floor force needs dt to calculate threshold to "stop" a slow voxel into static friction.
//fricForce = curForce - fricForce;
//assert(!(curForce.x != curForce.x) || !(curForce.y != curForce.y) || !(curForce.z != curForce.z)); //assert non QNAN
// linMom.add(curForce).multiplyScalar(dt);
// var translate=linMom.clone().multiplyScalar(dt*massInverse);//??massInverse
// // we need to check for friction conditions here (after calculating the translation) and stop things accordingly
// if (isFloorEnabled() && floorPenetration() >= 0){ //we must catch a slowing voxel here since it all boils down to needing access to the dt of this timestep.
// double work = fricForce.x*translate.x + fricForce.y*translate.y; //F dot disp
// double hKe = 0.5*mat->_massInverse*(linMom.x*linMom.x + linMom.y*linMom.y); //horizontal kinetic energy
// pos.add(translate);
// node.currPosition=pos.clone();
// node.displacement={
// x:translate.x+node.displacement.x,
// y:translate.y+node.displacement.y,
// z:translate.z+node.displacement.z};
// pos += translate;
//Rotation
}
function force(node) {
//forces from internal bonds
var inverseMass=1.0;
var gravity=new THREE.Vector3(0,-9.81,0);
var Cd = 0.47; // Dimensionless
var rho = 1.22; // kg / m^3
var v=1; //volume or area
var totalForce=new THREE.Vector3(0,0,0);
// Drag force:
// var drag=
totalForce.add(new THREE.Vector3(node.force.x,node.force.y,node.force.z));
totalForce.add(gravity);
var Fd = node.velocity.clone().multiplyScalar(-1/2 * Cd * rho*v ).multiply( node.velocity );
//totalForce.add(Fd);
totalForce.add(node.intForce);
// for (int i=0; i<6; i++){
// if (links[i]) totalForce += links[i]->force(isNegative((linkDirection)i)); //total force in LCS
// }
// totalForce = RotateVec3D(node.orient,totalForce); //from local to global coordinates
//assert(!(totalForce.x != totalForce.x) || !(totalForce.y != totalForce.y) || !(totalForce.z != totalForce.z)); //assert non QNAN
//other forces
// if (externalExists()) totalForce += external()->force(); //external forces
// totalForce -= velocity()*mat->globalDampingTranslateC(); //global damping f-cv
// totalForce.z += mat->gravityForce(); //gravity, according to f=mg
// if (isCollisionsEnabled()){
// for (std::vector<CVX_Collision*>::iterator it=colWatch->begin(); it!=colWatch->end(); it++){
// totalForce -= (*it)->contactForce(this);
// }
// }
//todo make internal forces 0 again
node.intForce=new THREE.Vector3(0,0,0);
// node.force.x=0;
// node.force.y=0;
// node.force.z=0;
return totalForce;
}