cyclone-physics 1.1.2 → 1.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/collisions.js +43 -23
- package/scripts/processors.js +10 -1
package/package.json
CHANGED
package/scripts/collisions.js
CHANGED
|
@@ -9,6 +9,8 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
9
9
|
// closure scratch variables
|
|
10
10
|
var thispos = new THREE.Vector3(),
|
|
11
11
|
otherpos = new THREE.Vector3(),
|
|
12
|
+
thisvel = new THREE.Vector3(),
|
|
13
|
+
othervel = new THREE.Vector3(),
|
|
12
14
|
midline = new THREE.Vector3(),
|
|
13
15
|
scaledVelocity = new THREE.Vector3(),
|
|
14
16
|
intersectionPoint = new THREE.Vector3();
|
|
@@ -20,9 +22,6 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
20
22
|
obj1.body.localToWorldPos(thispos.set(0,0,0));
|
|
21
23
|
obj2.body.localToWorldPos(otherpos.set(0,0,0));
|
|
22
24
|
|
|
23
|
-
let scaledRadius1 = obj1.radius * Math.max(obj1.body.scaleWorld.x, obj1.body.scaleWorld.y, obj1.body.scaleWorld.z),
|
|
24
|
-
scaledRadius2 = obj2.radius * Math.max(obj2.body.scaleWorld.x, obj2.body.scaleWorld.y, obj2.body.scaleWorld.z);
|
|
25
|
-
|
|
26
25
|
let dynamic = true; // TODO - this should either be a flag on rigid bodies, or a configurable threshold based on velocity
|
|
27
26
|
if (!dynamic) {
|
|
28
27
|
midline.subVectors(otherpos, thispos),
|
|
@@ -45,9 +44,17 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
45
44
|
//console.log('crash a sphere-sphere', contact);
|
|
46
45
|
}
|
|
47
46
|
} else {
|
|
48
|
-
let r =
|
|
47
|
+
let r = obj1.radius + obj2.radius;
|
|
49
48
|
// FIXME - probably need to transform velocity into world coordinates as well
|
|
50
|
-
|
|
49
|
+
obj1.body.localToWorldDir(thisvel.copy(obj1.body.velocity));
|
|
50
|
+
obj2.body.localToWorldDir(othervel.copy(obj2.body.velocity));
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
let v = scaledVelocity.copy(thisvel).sub(othervel).multiplyScalar(dt);
|
|
54
|
+
|
|
55
|
+
midline.copy(thispos).sub(otherpos).normalize();
|
|
56
|
+
|
|
57
|
+
//if (midline.dot(scaledVelocity) > 0) return; // moving away, can't collide
|
|
51
58
|
|
|
52
59
|
let endpos = midline.copy(thispos).add(v);
|
|
53
60
|
|
|
@@ -61,7 +68,7 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
61
68
|
|
|
62
69
|
var contact = new elation.physics.contact_dynamic({
|
|
63
70
|
normal: normal,
|
|
64
|
-
point: normal.clone().multiplyScalar(
|
|
71
|
+
point: normal.clone().multiplyScalar(obj1.radius).add(thispos), // allocate point
|
|
65
72
|
penetrationTime: intersection.t,
|
|
66
73
|
bodies: [obj1.body, obj2.body],
|
|
67
74
|
});
|
|
@@ -637,20 +644,23 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
637
644
|
closest = new THREE.Vector3();
|
|
638
645
|
|
|
639
646
|
return function(capsule, sphere, contacts, dt) {
|
|
640
|
-
const
|
|
641
|
-
|
|
647
|
+
const capsuleScaledRadius = capsule.radius * Math.max(capsule.body.scale.x, capsule.body.scale.z),
|
|
648
|
+
combinedRadius = capsuleScaledRadius + sphere.radius,
|
|
649
|
+
capsuleDims = capsule.getDimensions();
|
|
642
650
|
sphere.body.localToWorldPos(point.set(0,0,0));
|
|
643
651
|
|
|
652
|
+
|
|
644
653
|
elation.physics.colliders.helperfuncs.closest_point_on_line(capsuleDims.start, capsuleDims.end, point, closest);
|
|
654
|
+
|
|
645
655
|
normal.subVectors(closest, point);
|
|
646
656
|
const distance = normal.length();
|
|
647
|
-
|
|
648
|
-
if (distance <=
|
|
657
|
+
|
|
658
|
+
if (distance <= combinedRadius) {
|
|
649
659
|
normal.divideScalar(distance);
|
|
650
660
|
let contact = new elation.physics.contact({
|
|
651
661
|
normal: normal.clone(), // allocate normal
|
|
652
|
-
point: closest.clone().add(normal.multiplyScalar(
|
|
653
|
-
penetration:
|
|
662
|
+
point: closest.clone().add(normal.multiplyScalar(capsuleScaledRadius)), // allocate point
|
|
663
|
+
penetration: combinedRadius - distance,
|
|
654
664
|
bodies: [capsule.body, sphere.body]
|
|
655
665
|
});
|
|
656
666
|
contacts.push(contact);
|
|
@@ -669,20 +679,23 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
669
679
|
|
|
670
680
|
let distSquared = elation.physics.colliders.helperfuncs.distancesquared_between_lines(capsule1Dims.start, capsule1Dims.end, capsule2Dims.start, capsule2Dims.end, p1, p2);
|
|
671
681
|
|
|
672
|
-
|
|
682
|
+
const capsule1ScaledRadius = capsule1.radius * Math.max(capsule1.body.scale.x, capsule1.body.scale.z),
|
|
683
|
+
capsule2ScaledRadius = capsule2.radius * Math.max(capsule2.body.scale.x, capsule2.body.scale.z);
|
|
684
|
+
|
|
685
|
+
if (distSquared <= Math.pow(capsule1ScaledRadius + capsule2ScaledRadius, 2)) {
|
|
673
686
|
console.log('CAPSULE COLLIDE', capsule1, capsule2);
|
|
674
687
|
let normal = new THREE.Vector3().subVectors(p2, p1),
|
|
675
688
|
point = p1.clone();
|
|
676
689
|
dist = Math.sqrt(distSquared);
|
|
677
690
|
normal.divideScalar(dist);
|
|
678
|
-
point.x += normal.x *
|
|
679
|
-
point.y += normal.y *
|
|
680
|
-
point.z += normal.z *
|
|
691
|
+
point.x += normal.x * capsule1ScaledRadius;
|
|
692
|
+
point.y += normal.y * capsule1ScaledRadius;
|
|
693
|
+
point.z += normal.z * capsule1ScaledRadius;
|
|
681
694
|
|
|
682
695
|
let contact = new elation.physics.contact({
|
|
683
696
|
normal: normal,
|
|
684
697
|
point: point,
|
|
685
|
-
penetration: dist - (
|
|
698
|
+
penetration: dist - (capsule1ScaledRadius + capsule2ScaledRadius),
|
|
686
699
|
bodies: [capsule1.body, capsule2.body]
|
|
687
700
|
});
|
|
688
701
|
contacts.push(contact);
|
|
@@ -796,13 +809,12 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
796
809
|
p3 = worldpoints.p3,
|
|
797
810
|
normal = worldpoints.normal;
|
|
798
811
|
|
|
799
|
-
|
|
800
|
-
|
|
812
|
+
let velNormal = spherevel.dot(normal);
|
|
801
813
|
|
|
802
814
|
// Check if we're already in contact
|
|
803
815
|
elation.physics.colliders.helperfuncs.closest_point_on_triangle(spherepos, p1, p2, p3, triangleClosestPoint);
|
|
804
816
|
let triangleDistSquared = triangleClosestPoint.distanceToSquared(spherepos)
|
|
805
|
-
if (triangleDistSquared < sphere.radius * sphere.radius) {
|
|
817
|
+
if (triangleDistSquared < sphere.radius * sphere.radius && velNormal <= 0) {
|
|
806
818
|
let contact = new elation.physics.contact({
|
|
807
819
|
normal: normal.clone(), // allocate normal
|
|
808
820
|
point: triangleClosestPoint.clone(), // allocate point
|
|
@@ -875,7 +887,7 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
875
887
|
intersectionPoint.y - triangleClosestPoint.y,
|
|
876
888
|
intersectionPoint.z - triangleClosestPoint.z
|
|
877
889
|
);
|
|
878
|
-
|
|
890
|
+
collisionNormal.normalize();
|
|
879
891
|
|
|
880
892
|
intersectionPoint.x += collisionNormal.x * -sphere.radius;
|
|
881
893
|
intersectionPoint.y += collisionNormal.y * -sphere.radius;
|
|
@@ -1687,6 +1699,8 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
1687
1699
|
let triangles = [];
|
|
1688
1700
|
let radiusSq = 0;
|
|
1689
1701
|
|
|
1702
|
+
this.body.updateState(); // ensure scaleWorld is up to date before processing triangles
|
|
1703
|
+
let doubleSided = false;
|
|
1690
1704
|
if (!this.modeldata && this.mesh && this.mesh.geometry) {
|
|
1691
1705
|
if (this.mesh.geometry instanceof THREE.BufferGeometry) {
|
|
1692
1706
|
this.modeldata = {
|
|
@@ -1702,6 +1716,7 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
1702
1716
|
}
|
|
1703
1717
|
}
|
|
1704
1718
|
}
|
|
1719
|
+
doubleSided = this.mesh.material.side == THREE.DoubleSide;
|
|
1705
1720
|
}
|
|
1706
1721
|
if (this.modeldata) {
|
|
1707
1722
|
if (this.modeldata.index) {
|
|
@@ -1727,6 +1742,11 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
1727
1742
|
if (!triangle.isDegenerate()) {
|
|
1728
1743
|
triangles.push(triangle);
|
|
1729
1744
|
|
|
1745
|
+
if (doubleSided) {
|
|
1746
|
+
let triangle2 = new elation.physics.colliders.triangle(this.body, [p3, p2, p1]);
|
|
1747
|
+
triangles.push(triangle2);
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1730
1750
|
let l1 = p1.lengthSq(),
|
|
1731
1751
|
l2 = p2.lengthSq(),
|
|
1732
1752
|
l3 = p3.lengthSq();
|
|
@@ -1761,7 +1781,7 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
1761
1781
|
}
|
|
1762
1782
|
}
|
|
1763
1783
|
}
|
|
1764
|
-
this.radius = Math.sqrt(radiusSq);
|
|
1784
|
+
this.radius = Math.sqrt(radiusSq) * Math.max(this.body.scaleWorld.x, this.body.scaleWorld.y, this.body.scaleWorld.z);
|
|
1765
1785
|
this.boundingSphere.radius = this.radius;
|
|
1766
1786
|
return triangles;
|
|
1767
1787
|
}
|
|
@@ -1797,11 +1817,11 @@ elation.require(['physics.common', 'utils.math'], function() {
|
|
|
1797
1817
|
bodies[obj.uuid].scale.copy(obj.scale);
|
|
1798
1818
|
bodies[obj.uuid].orientation.copy(obj.quaternion);
|
|
1799
1819
|
bodies[obj.uuid].object = this.body.object;
|
|
1820
|
+
parent.add(bodies[obj.uuid]);
|
|
1800
1821
|
if (obj instanceof THREE.Mesh) {
|
|
1801
1822
|
bodies[obj.uuid].setCollider('mesh', {mesh: obj, isroot: false });
|
|
1802
1823
|
//elation.events.add(bodies[obj.uuid], 'physics_collide', (ev) => elation.events.fire({type: 'physics_collide', element: this.body, event: ev}));
|
|
1803
1824
|
}
|
|
1804
|
-
parent.add(bodies[obj.uuid]);
|
|
1805
1825
|
}
|
|
1806
1826
|
parent = bodies[obj.uuid];
|
|
1807
1827
|
}
|
package/scripts/processors.js
CHANGED
|
@@ -53,6 +53,7 @@ elation.require(["physics.common"], function() {
|
|
|
53
53
|
var obj1 = potentialpair[0], obj2 = potentialpair[1];
|
|
54
54
|
// Get list of all contact points between the two objects
|
|
55
55
|
var contacts = obj1.getContacts(obj2, [], t);
|
|
56
|
+
/*
|
|
56
57
|
if (contacts && contacts.length > 0) {
|
|
57
58
|
// Resolve the deepest contact first
|
|
58
59
|
var deepest = this.getDeepestContact(contacts);
|
|
@@ -60,6 +61,14 @@ elation.require(["physics.common"], function() {
|
|
|
60
61
|
obj1.state.colliding = true;
|
|
61
62
|
obj2.state.colliding = true;
|
|
62
63
|
}
|
|
64
|
+
*/
|
|
65
|
+
if (contacts && contacts.length > 0) {
|
|
66
|
+
for (let i = 0; i < contacts.length; i++) {
|
|
67
|
+
collisions.push(contacts[i]);
|
|
68
|
+
obj1.state.colliding = true;
|
|
69
|
+
obj2.state.colliding = true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
63
72
|
}
|
|
64
73
|
//console.log(potentials.length + ' potential crashes:', potentials, collisions);
|
|
65
74
|
}
|
|
@@ -103,7 +112,7 @@ elation.require(["physics.common"], function() {
|
|
|
103
112
|
let contact = contacts.shift();
|
|
104
113
|
contact.resolve(t, linearChange, angularChange, contacts);
|
|
105
114
|
// console.log('blah', contacts.length, linearChange[1].toArray().map(x => +x.toFixed(4)), contact.bodies)
|
|
106
|
-
break;
|
|
115
|
+
//break;
|
|
107
116
|
}
|
|
108
117
|
}
|
|
109
118
|
});
|