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
|
/*global octtree, vec3 */
function Newton() {
}
Newton.prototype.friction = 100;
Newton.prototype.update = function (elapsed, obj) {
var incr;
vec3.scale(obj.velocity, 1 - (this.friction * elapsed));
incr = vec3.create(obj.velocity);
vec3.scale(incr, elapsed);
vec3.add(obj.pos, incr, obj.next_pos);
};
function Spring() {
}
Spring.prototype.k = 1;
Spring.prototype.equilibriumLength = 2;
Spring.prototype.push = true;
Spring.prototype.pull = true;
Spring.prototype.dampingFactor = 0.5;
Spring.prototype.octtreeRadius = 4;
Spring.prototype.octtreeLimit = 40;
Spring.prototype.apply = function (elapsed, obj1, obj2) {
var damper, vecOP, distanceOP, x;
damper = this.dampingFactor * elapsed * 100000;
vecOP = vec3.create();
distanceOP = 0;
x = 0;
vec3.subtract(obj2.pos, obj1.pos, vecOP);
distanceOP = vec3.length(vecOP);
if (!isNaN(distanceOP) && 0 !== distanceOP) {
x = distanceOP - this.equilibriumLength;
if (distanceOP > this.equilibriumLength && !this.pull) {
return;
}
if (distanceOP < this.equilibriumLength && !this.push) {
return;
}
vec3.scale(vecOP, (damper * (((1 / distanceOP) * x) / obj1.mass)));
vec3.add(obj1.velocity, vecOP);
}
};
Spring.prototype.update = function (elapsed, tree, obj) {
var damper, vecOP, distanceOP, x, found, i, obj1;
damper = this.dampingFactor * elapsed * 100000;
vecOP = vec3.create();
distanceOP = 0;
x = 0;
found = tree.findInRadius(obj.pos, this.octtreeRadius, this.octtreeLimit);
for (i = 0; i < found.length; i += 1) {
obj1 = found[i].value;
if (obj1 !== obj) {
// F = -k x where x is difference from equilibriumLength
// a = F / m
vec3.subtract(obj1.pos, obj.pos, vecOP);
distanceOP = vec3.length(vecOP);
if (!isNaN(distanceOP) && 0 !== distanceOP) {
x = distanceOP - this.equilibriumLength;
if (distanceOP > this.equilibriumLength && !this.pull) {
continue;
}
if (distanceOP < this.equilibriumLength && !this.push) {
continue;
}
vec3.scale(vecOP,
(damper * (((1 / distanceOP) * x) / obj.mass)));
vec3.add(obj.velocity, vecOP);
}
}
}
};
function Gravity() {
}
Gravity.prototype.bigG = 1 / 20;
Gravity.prototype.octtreeRadius = 5;
Gravity.prototype.octtreeLimit = 20;
Gravity.prototype.repel = false;
Gravity.prototype.update = function (elapsed, tree, obj) {
var vecOP, distanceOP, found, i, obj1;
vecOP = vec3.create();
distanceOP = 0;
found = tree.findInRadius(obj.pos, this.octtreeRadius, this.octtreeLimit);
for (i = 0; i < found.length; i += 1) {
obj1 = found[i].value;
if (obj1 !== obj) {
// F = G.m1.m2 / (d.d)
// a = F / m1
// thus a = G.m2/(d.d)
vec3.subtract(obj1.pos, obj.pos, vecOP);
distanceOP = vec3.length(vecOP);
if ((!(isNaN(distanceOP))) && 0 !== distanceOP) {
vec3.scale(vecOP, (this.bigG * obj1.mass) /
(distanceOP * distanceOP));
if (this.repel) {
vec3.subtract(obj.velocity, vecOP);
} else {
vec3.add(obj.velocity, vecOP);
}
}
}
}
};
|