hyperstellar 0.1.65__tar.gz → 0.1.67__tar.gz
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.
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/PKG-INFO +1 -1
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar/_native/windows-x64/shaders/math.comp +50 -66
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar/_native/windows-x64/stellar.pyd +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar.egg-info/PKG-INFO +1 -1
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/pyproject.toml +3 -1
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/LICENSE +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/README.md +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar/__init__.py +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar/__init__.pyi +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar/_native/windows-x64/shaders/quad.frag +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar/_native/windows-x64/shaders/quad.geom +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar/_native/windows-x64/shaders/quad.vert +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar/py.typed +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar.egg-info/SOURCES.txt +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar.egg-info/dependency_links.txt +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar.egg-info/top_level.txt +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/setup.cfg +0 -0
- {hyperstellar-0.1.65 → hyperstellar-0.1.67}/tests/test.py +0 -0
|
@@ -1110,7 +1110,7 @@ void applyConstraints(inout vec2 pos, inout vec2 vel, int objectIndex, vec2 orig
|
|
|
1110
1110
|
}
|
|
1111
1111
|
|
|
1112
1112
|
// ============================================================================
|
|
1113
|
-
// COLLISION DETECTION FUNCTIONS
|
|
1113
|
+
// COLLISION DETECTION FUNCTIONS
|
|
1114
1114
|
// ============================================================================
|
|
1115
1115
|
|
|
1116
1116
|
// Circle-Circle collision detection
|
|
@@ -1137,35 +1137,41 @@ CollisionInfo detectCircleCircle(vec2 posA, float radiusA, vec2 posB, float radi
|
|
|
1137
1137
|
return info;
|
|
1138
1138
|
}
|
|
1139
1139
|
|
|
1140
|
-
//
|
|
1141
|
-
CollisionInfo detectAABBAABB(vec2
|
|
1140
|
+
// Hybrid AABB detection: current positions for penetration, old positions for normal direction
|
|
1141
|
+
CollisionInfo detectAABBAABB(vec2 posA_curr, vec2 halfExtA, vec2 posB_curr, vec2 halfExtB,
|
|
1142
|
+
vec2 posA_old, vec2 posB_old, int objB)
|
|
1142
1143
|
{
|
|
1143
1144
|
CollisionInfo info;
|
|
1144
1145
|
info.hasCollision = false;
|
|
1145
1146
|
info.otherObjectID = objB;
|
|
1146
|
-
|
|
1147
|
-
//
|
|
1148
|
-
vec2
|
|
1149
|
-
vec2 overlap = halfExtA + halfExtB - abs(
|
|
1150
|
-
|
|
1151
|
-
// Check for overlap on both axes
|
|
1147
|
+
|
|
1148
|
+
// Penetration uses CURRENT (predicted/selfNew) positions
|
|
1149
|
+
vec2 delta_curr = posB_curr - posA_curr;
|
|
1150
|
+
vec2 overlap = halfExtA + halfExtB - abs(delta_curr);
|
|
1151
|
+
|
|
1152
1152
|
if (overlap.x > 0.0 && overlap.y > 0.0)
|
|
1153
1153
|
{
|
|
1154
1154
|
info.hasCollision = true;
|
|
1155
|
-
|
|
1156
|
-
//
|
|
1157
|
-
|
|
1155
|
+
|
|
1156
|
+
// Normal direction uses OLD positions (physically correct side)
|
|
1157
|
+
vec2 delta_old = posB_old - posA_old;
|
|
1158
|
+
|
|
1159
|
+
// Choose the MINIMUM overlap axis — that's the separation axis
|
|
1160
|
+
if (overlap.x < overlap.y ||
|
|
1161
|
+
(abs(overlap.x - overlap.y) < 0.001 && abs(delta_old.x) >= abs(delta_old.y)))
|
|
1158
1162
|
{
|
|
1159
|
-
|
|
1163
|
+
// Minimum penetration is along X — push along X
|
|
1164
|
+
info.normal = vec2(sign(delta_old.x), 0.0);
|
|
1160
1165
|
info.penetration = overlap.x;
|
|
1161
1166
|
}
|
|
1162
1167
|
else
|
|
1163
1168
|
{
|
|
1164
|
-
|
|
1169
|
+
// Minimum penetration is along Y — push along Y
|
|
1170
|
+
info.normal = vec2(0.0, sign(delta_old.y));
|
|
1165
1171
|
info.penetration = overlap.y;
|
|
1166
1172
|
}
|
|
1167
1173
|
}
|
|
1168
|
-
|
|
1174
|
+
|
|
1169
1175
|
return info;
|
|
1170
1176
|
}
|
|
1171
1177
|
|
|
@@ -1387,43 +1393,38 @@ CollisionInfo detectCirclePolygon(vec2 circlePos, float circleRadius,
|
|
|
1387
1393
|
return info;
|
|
1388
1394
|
}
|
|
1389
1395
|
|
|
1390
|
-
// Master collision detection dispatcher
|
|
1391
|
-
CollisionInfo detectCollision(Object objA, Object objB, int objIndexB
|
|
1396
|
+
// Master collision detection dispatcher - hybrid for AABB
|
|
1397
|
+
CollisionInfo detectCollision(Object objA, Object objB, int objIndexB,
|
|
1398
|
+
vec2 posA_old, vec2 posB_old)
|
|
1392
1399
|
{
|
|
1393
1400
|
CollisionInfo info;
|
|
1394
1401
|
info.hasCollision = false;
|
|
1395
1402
|
|
|
1396
|
-
// Get collision properties for both objects
|
|
1397
1403
|
CollisionProperties propsA = collisionProps[gl_GlobalInvocationID.x];
|
|
1398
1404
|
CollisionProperties propsB = collisionProps[objIndexB];
|
|
1399
1405
|
|
|
1400
|
-
// Check if collisions are enabled for both objects
|
|
1401
1406
|
if (propsA.enabled == 0 || propsB.enabled == 0)
|
|
1402
1407
|
return info;
|
|
1403
1408
|
|
|
1404
1409
|
int shapeA = propsA.shapeType;
|
|
1405
1410
|
int shapeB = propsB.shapeType;
|
|
1406
1411
|
|
|
1407
|
-
// Skip if either object has no collision shape
|
|
1408
1412
|
if (shapeA == COLLISION_NONE || shapeB == COLLISION_NONE)
|
|
1409
1413
|
return info;
|
|
1410
1414
|
|
|
1411
|
-
// Dispatch to appropriate collision detection function based on shape types
|
|
1412
1415
|
if (shapeA == COLLISION_CIRCLE && shapeB == COLLISION_CIRCLE)
|
|
1413
1416
|
{
|
|
1414
|
-
// Circle vs Circle
|
|
1415
1417
|
info = detectCircleCircle(objA.position, objA.visualData.x,
|
|
1416
1418
|
objB.position, objB.visualData.x, objIndexB);
|
|
1417
1419
|
}
|
|
1418
|
-
// AABB vs AABB
|
|
1419
1420
|
else if (shapeA == COLLISION_AABB && shapeB == COLLISION_AABB)
|
|
1420
1421
|
{
|
|
1421
1422
|
vec2 halfExtA = objA.visualData.xy * 0.5;
|
|
1422
1423
|
vec2 halfExtB = objB.visualData.xy * 0.5;
|
|
1423
1424
|
info = detectAABBAABB(objA.position, halfExtA,
|
|
1424
|
-
|
|
1425
|
+
objB.position, halfExtB,
|
|
1426
|
+
posA_old, posB_old, objIndexB);
|
|
1425
1427
|
}
|
|
1426
|
-
// Polygon vs Polygon
|
|
1427
1428
|
else if (shapeA == COLLISION_POLYGON && shapeB == COLLISION_POLYGON)
|
|
1428
1429
|
{
|
|
1429
1430
|
info = detectPolygonPolygon(
|
|
@@ -1431,7 +1432,6 @@ CollisionInfo detectCollision(Object objA, Object objB, int objIndexB)
|
|
|
1431
1432
|
objB.position, objB.visualData.x, int(objB.visualData.y), objB.visualData.z,
|
|
1432
1433
|
objIndexB);
|
|
1433
1434
|
}
|
|
1434
|
-
// Circle vs AABB
|
|
1435
1435
|
else if (shapeA == COLLISION_CIRCLE && shapeB == COLLISION_AABB)
|
|
1436
1436
|
{
|
|
1437
1437
|
vec2 halfExtB = objB.visualData.xy * 0.5;
|
|
@@ -1440,13 +1440,11 @@ CollisionInfo detectCollision(Object objA, Object objB, int objIndexB)
|
|
|
1440
1440
|
}
|
|
1441
1441
|
else if (shapeA == COLLISION_AABB && shapeB == COLLISION_CIRCLE)
|
|
1442
1442
|
{
|
|
1443
|
-
// Swap roles and flip normal
|
|
1444
1443
|
vec2 halfExtA = objA.visualData.xy * 0.5;
|
|
1445
1444
|
info = detectCircleAABB(objB.position, objB.visualData.x,
|
|
1446
1445
|
objA.position, halfExtA, objIndexB);
|
|
1447
|
-
info.normal = -info.normal;
|
|
1446
|
+
info.normal = -info.normal;
|
|
1448
1447
|
}
|
|
1449
|
-
// Circle vs Polygon
|
|
1450
1448
|
else if (shapeA == COLLISION_CIRCLE && shapeB == COLLISION_POLYGON)
|
|
1451
1449
|
{
|
|
1452
1450
|
info = detectCirclePolygon(objA.position, objA.visualData.x,
|
|
@@ -1460,15 +1458,14 @@ CollisionInfo detectCollision(Object objA, Object objB, int objIndexB)
|
|
|
1460
1458
|
objA.position, objA.visualData.x,
|
|
1461
1459
|
int(objA.visualData.y), objA.visualData.z,
|
|
1462
1460
|
objIndexB);
|
|
1463
|
-
info.normal = -info.normal;
|
|
1461
|
+
info.normal = -info.normal;
|
|
1464
1462
|
}
|
|
1465
|
-
// AABB vs Polygon (simplified - treat polygon as circle for collision)
|
|
1466
1463
|
else if (shapeA == COLLISION_AABB && shapeB == COLLISION_POLYGON)
|
|
1467
1464
|
{
|
|
1468
1465
|
vec2 halfExtA = objA.visualData.xy * 0.5;
|
|
1469
1466
|
info = detectCircleAABB(objB.position, objB.visualData.x,
|
|
1470
1467
|
objA.position, halfExtA, objIndexB);
|
|
1471
|
-
info.normal = -info.normal;
|
|
1468
|
+
info.normal = -info.normal;
|
|
1472
1469
|
}
|
|
1473
1470
|
else if (shapeA == COLLISION_POLYGON && shapeB == COLLISION_AABB)
|
|
1474
1471
|
{
|
|
@@ -1480,10 +1477,6 @@ CollisionInfo detectCollision(Object objA, Object objB, int objIndexB)
|
|
|
1480
1477
|
return info;
|
|
1481
1478
|
}
|
|
1482
1479
|
|
|
1483
|
-
// ============================================================================
|
|
1484
|
-
// RESEARCH-GRADE COLLISION RESOLUTION SYSTEM
|
|
1485
|
-
// ============================================================================
|
|
1486
|
-
|
|
1487
1480
|
// ============================================================================
|
|
1488
1481
|
// BASIC COLLISION RESPONSE (Momentum-Conserving)
|
|
1489
1482
|
// ============================================================================
|
|
@@ -1874,10 +1867,10 @@ void main() {
|
|
|
1874
1867
|
applyConstraints(new_pos, new_vel, objectIndex, originalPos);
|
|
1875
1868
|
|
|
1876
1869
|
// ========================================================================
|
|
1877
|
-
// COLLISION HANDLING -
|
|
1870
|
+
// COLLISION HANDLING - Hybrid AABB + safe normal direction
|
|
1878
1871
|
// ========================================================================
|
|
1879
1872
|
vec2 collision_vel = new_vel;
|
|
1880
|
-
vec2 final_pos = new_pos;
|
|
1873
|
+
vec2 final_pos = new_pos;
|
|
1881
1874
|
bool had_collision = false;
|
|
1882
1875
|
|
|
1883
1876
|
for (int i = 0; i < uNumObjects; i++) {
|
|
@@ -1885,8 +1878,7 @@ void main() {
|
|
|
1885
1878
|
|
|
1886
1879
|
Object other = objectsIn[i];
|
|
1887
1880
|
|
|
1888
|
-
|
|
1889
|
-
CollisionInfo collision = detectCollision(selfNew, other, i); // <--- selfNew here
|
|
1881
|
+
CollisionInfo collision = detectCollision(selfNew, other, i, p.position, other.position);
|
|
1890
1882
|
|
|
1891
1883
|
if (collision.hasCollision) {
|
|
1892
1884
|
had_collision = true;
|
|
@@ -1900,24 +1892,28 @@ void main() {
|
|
|
1900
1892
|
float massA = mass;
|
|
1901
1893
|
float massB = max(EPSILON, other.mass);
|
|
1902
1894
|
|
|
1903
|
-
//
|
|
1895
|
+
// === ENSURE NORMAL POINTS AWAY FROM THIS OBJECT ===
|
|
1896
|
+
vec2 fromOther = selfNew.position - other.position;
|
|
1897
|
+
if (dot(collision.normal, fromOther) < 0.0) {
|
|
1898
|
+
collision.normal = -collision.normal;
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
// Velocity impulse
|
|
1904
1902
|
vec2 relativeVel = other.velocity - collision_vel;
|
|
1905
1903
|
float velAlongNormal = dot(relativeVel, collision.normal);
|
|
1906
1904
|
|
|
1907
|
-
if (velAlongNormal < 0.0) {
|
|
1905
|
+
if (velAlongNormal < 0.0) {
|
|
1908
1906
|
float e = clamp(restitution, 0.0, 1.0);
|
|
1909
|
-
float j = -(1.0 + e) * velAlongNormal / (1.0
|
|
1910
|
-
|
|
1907
|
+
float j = -(1.0 + e) * velAlongNormal / (1.0/massA + 1.0/massB);
|
|
1911
1908
|
collision_vel -= (j * collision.normal) / massA;
|
|
1912
1909
|
|
|
1913
|
-
// Friction - conservative
|
|
1914
1910
|
if (friction > 0.0) {
|
|
1915
1911
|
vec2 tangent = relativeVel - collision.normal * dot(relativeVel, collision.normal);
|
|
1916
1912
|
float tLen = length(tangent);
|
|
1917
|
-
if (tLen >
|
|
1913
|
+
if (tLen > 0.01) {
|
|
1918
1914
|
tangent = normalize(tangent);
|
|
1919
1915
|
float vt = dot(relativeVel, tangent);
|
|
1920
|
-
float jt = -vt * friction
|
|
1916
|
+
float jt = -vt * friction * 0.5;
|
|
1921
1917
|
float maxJt = abs(j) * friction;
|
|
1922
1918
|
jt = clamp(jt, -maxJt, maxJt);
|
|
1923
1919
|
collision_vel -= (jt * tangent) / massA;
|
|
@@ -1925,19 +1921,13 @@ void main() {
|
|
|
1925
1921
|
}
|
|
1926
1922
|
}
|
|
1927
1923
|
|
|
1928
|
-
// Position correction -
|
|
1929
|
-
const float slop = 0.
|
|
1930
|
-
const float percent = 0.
|
|
1924
|
+
// Position correction - conservative for stability
|
|
1925
|
+
const float slop = 0.045;
|
|
1926
|
+
const float percent = 0.62;
|
|
1931
1927
|
|
|
1932
1928
|
if (collision.penetration > slop) {
|
|
1933
1929
|
float totalMass = massA + massB;
|
|
1934
1930
|
vec2 correction = collision.normal * (collision.penetration - slop) * percent * (massB / totalMass);
|
|
1935
|
-
|
|
1936
|
-
// Force correction direction away from the other object
|
|
1937
|
-
if (dot(collision.normal, other.position - selfNew.position) < 0.0) {
|
|
1938
|
-
correction = -correction;
|
|
1939
|
-
}
|
|
1940
|
-
|
|
1941
1931
|
final_pos -= correction;
|
|
1942
1932
|
}
|
|
1943
1933
|
}
|
|
@@ -1946,10 +1936,10 @@ void main() {
|
|
|
1946
1936
|
if (had_collision) {
|
|
1947
1937
|
new_vel = sanitizeVec2(collision_vel);
|
|
1948
1938
|
}
|
|
1949
|
-
new_pos = sanitizeVec2(final_pos);
|
|
1939
|
+
new_pos = sanitizeVec2(final_pos);
|
|
1950
1940
|
|
|
1951
1941
|
// ========================================================================
|
|
1952
|
-
// REST OF CODE(
|
|
1942
|
+
// REST OF CODE (age contacts, final sanity, write output)
|
|
1953
1943
|
// ========================================================================
|
|
1954
1944
|
|
|
1955
1945
|
// Age out old contacts for this object
|
|
@@ -1961,20 +1951,14 @@ void main() {
|
|
|
1961
1951
|
new_pos = sanitizeVec2(new_pos);
|
|
1962
1952
|
new_vel = sanitizeVec2(new_vel);
|
|
1963
1953
|
|
|
1964
|
-
//
|
|
1965
|
-
// FINAL SANITY CHECKS
|
|
1966
|
-
// ========================================================================
|
|
1967
|
-
|
|
1968
|
-
// Ensure velocities aren't excessive
|
|
1954
|
+
// Final sanity checks
|
|
1969
1955
|
float maxSpeed = 1000.0;
|
|
1970
1956
|
float currentSpeed = length(new_vel);
|
|
1971
1957
|
if (currentSpeed > maxSpeed) {
|
|
1972
1958
|
new_vel = normalize(new_vel) * maxSpeed;
|
|
1973
1959
|
}
|
|
1974
1960
|
|
|
1975
|
-
//
|
|
1976
|
-
// WRITE UPDATED OBJECT STATE
|
|
1977
|
-
// ========================================================================
|
|
1961
|
+
// Write updated object state
|
|
1978
1962
|
objectsOut[gid].position = new_pos;
|
|
1979
1963
|
objectsOut[gid].velocity = new_vel;
|
|
1980
1964
|
objectsOut[gid].mass = mass;
|
|
Binary file
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "hyperstellar"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.67"
|
|
8
8
|
description = "GPU-accelerated physics simulation engine"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{name = "Aiden Jabari", email = "Jabariaiden15@email.com"}]
|
|
@@ -63,6 +63,8 @@ where = ["hyperstellar/src"]
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
|
|
66
|
+
|
|
67
|
+
|
|
66
68
|
|
|
67
69
|
|
|
68
70
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{hyperstellar-0.1.65 → hyperstellar-0.1.67}/hyperstellar/src/hyperstellar.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|