hyperstellar 0.1.73__tar.gz → 0.1.74__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.
Files changed (18) hide show
  1. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/PKG-INFO +1 -1
  2. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar/_native/windows-x64/shaders/math.comp +120 -104
  3. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar/_native/windows-x64/stellar.pyd +0 -0
  4. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar.egg-info/PKG-INFO +1 -1
  5. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/pyproject.toml +2 -1
  6. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/LICENSE +0 -0
  7. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/README.md +0 -0
  8. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar/__init__.py +0 -0
  9. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar/__init__.pyi +0 -0
  10. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar/_native/windows-x64/shaders/quad.frag +0 -0
  11. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar/_native/windows-x64/shaders/quad.geom +0 -0
  12. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar/_native/windows-x64/shaders/quad.vert +0 -0
  13. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar/py.typed +0 -0
  14. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar.egg-info/SOURCES.txt +0 -0
  15. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar.egg-info/dependency_links.txt +0 -0
  16. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/hyperstellar/src/hyperstellar.egg-info/top_level.txt +0 -0
  17. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/setup.cfg +0 -0
  18. {hyperstellar-0.1.73 → hyperstellar-0.1.74}/tests/test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperstellar
3
- Version: 0.1.73
3
+ Version: 0.1.74
4
4
  Summary: GPU-accelerated physics simulation engine
5
5
  Author-email: Aiden Jabari <Jabariaiden15@email.com>
6
6
  License: MIT License
@@ -1742,6 +1742,33 @@ void ageContacts(int objectIndex) {
1742
1742
  }
1743
1743
  }
1744
1744
 
1745
+ // Estimate world contact point between two objects after collision detection.
1746
+ // Uses shape types to give a reasonable point for torque calculation.
1747
+ vec2 getContactPoint(Object objA, Object objB, vec2 normal, float penetration) {
1748
+ CollisionProperties propsA = collisionProps[gl_GlobalInvocationID.x];
1749
+ int shapeA = propsA.shapeType;
1750
+ float radiusA = objA.visualData.x;
1751
+ vec2 halfExtA = objA.visualData.xy * 0.5;
1752
+
1753
+ // For circle: contact point is along normal at radius distance from centre
1754
+ if (shapeA == COLLISION_CIRCLE) {
1755
+ return objA.position - normal * radiusA;
1756
+ }
1757
+ // For AABB or polygon: estimate deepest point along normal
1758
+ else if (shapeA == COLLISION_AABB || shapeA == COLLISION_POLYGON) {
1759
+ // Approximate using the other object's AABB clamp method (from user snippet)
1760
+ vec2 otherHalfExt = objB.visualData.xy * 0.5;
1761
+ vec2 otherMin = objB.position - otherHalfExt;
1762
+ vec2 otherMax = objB.position + otherHalfExt;
1763
+ // Clamp object A's centre to object B's AABB - gives a point inside B
1764
+ vec2 closest = clamp(objA.position, otherMin, otherMax);
1765
+ return closest;
1766
+ }
1767
+ // Fallback: centre of object A
1768
+ return objA.position;
1769
+ }
1770
+
1771
+
1745
1772
  // ============================================================================
1746
1773
  // MAIN COMPUTE SHADER ENTRY POINT - UPDATED WITH FIXED COLLISION RESOLUTION
1747
1774
  // ============================================================================
@@ -1866,7 +1893,7 @@ void main() {
1866
1893
  new_rotation = mod(new_rotation, 2.0 * PI); // Wrap rotation
1867
1894
 
1868
1895
  // ========================================================================
1869
- // WORLD BOUNDARIES
1896
+ // WORLD BOUNDARIES (UNCHANGED)
1870
1897
  // ========================================================================
1871
1898
  const vec2 world_min = vec2(-1000000.0, -1000000.0);
1872
1899
  const vec2 world_max = vec2(1000000.0, 1000000.0);
@@ -1900,131 +1927,124 @@ void main() {
1900
1927
  // CONSTRAINT RESOLUTION (UNCHANGED)
1901
1928
  // ========================================================================
1902
1929
  applyConstraints(new_pos, new_vel, objectIndex, originalPos);
1903
-
1904
- // ========================================================================
1905
- // NEW: COLLISION SYSTEM - FIXED FOR PARALLEL EXECUTION
1906
- // ========================================================================
1907
-
1908
- // Strategy:
1909
- // 1. Each thread only modifies its OWN object's velocity
1910
- // 2. Use impulses that conserve momentum without modifying other objects
1911
- // 3. Position correction happens AFTER all velocity updates
1912
-
1913
- vec2 collision_vel = new_vel;
1914
- bool had_collision = false;
1915
-
1916
- // Check collisions with ALL other objects (not just higher indices)
1917
- for (int i = 0; i < uNumObjects; i++) {
1918
- if (i == objectIndex) continue; // Skip self
1919
-
1920
- Object other = objectsIn[i];
1921
1930
 
1922
- // Detect collision
1923
- CollisionInfo collision = detectCollision(p, other, i);
1924
-
1925
- if (collision.hasCollision) {
1926
- had_collision = true;
1927
-
1928
- // Get collision properties
1929
- CollisionProperties propsA = collisionProps[objectIndex];
1930
- CollisionProperties propsB = collisionProps[i];
1931
-
1932
- // Calculate effective properties
1933
- float restitution = min(propsA.restitution, propsB.restitution);
1934
- float friction = sqrt(propsA.friction * propsB.friction);
1931
+ // ========================================================================
1932
+ // NEW COLLISION SYSTEM - ANTI-STICKING IMPULSE + TORQUE
1933
+ // ========================================================================
1934
+ vec2 collision_vel = new_vel;
1935
+ bool had_collision = false;
1936
+
1937
+ // Precompute inertia for torque (square plate approximation)
1938
+ float halfW = p.visualData.x * 0.5;
1939
+ float halfH = p.visualData.y * 0.5;
1940
+ float inertia = mass * (halfW * halfW + halfH * halfH) / 6.0;
1941
+ if (inertia < EPSILON) inertia = EPSILON;
1942
+ float accumulated_torque = 0.0;
1943
+
1944
+ // Check collisions with ALL other objects
1945
+ for (int i = 0; i < uNumObjects; i++) {
1946
+ if (i == objectIndex) continue; // Skip self
1935
1947
 
1936
- // Get masses
1937
- float massA = mass;
1938
- float massB = max(EPSILON, other.mass);
1948
+ Object other = objectsIn[i];
1939
1949
 
1940
- // Relative velocity
1941
- vec2 relativeVel = other.velocity - collision_vel;
1942
- float velocityAlongNormal = dot(relativeVel, collision.normal);
1950
+ // Detect collision
1951
+ CollisionInfo collision = detectCollision(p, other, i);
1943
1952
 
1944
- // Only resolve if moving toward each other
1945
- if (velocityAlongNormal < 0.0) {
1946
- // Calculate impulse (standard rigid body physics)
1947
- float e = clamp(restitution, 0.0, 1.0);
1948
- float j = -(1.0 + e) * velocityAlongNormal;
1949
- j /= (1.0 / massA + 1.0 / massB);
1953
+ if (collision.hasCollision) {
1954
+ had_collision = true;
1955
+
1956
+ // Get collision properties
1957
+ CollisionProperties propsA = collisionProps[objectIndex];
1958
+ CollisionProperties propsB = collisionProps[i];
1959
+
1960
+ // Calculate effective properties
1961
+ float restitution = min(propsA.restitution, propsB.restitution);
1962
+ float friction = sqrt(propsA.friction * propsB.friction);
1950
1963
 
1951
- // Apply impulse to THIS object only
1952
- vec2 impulse = j * collision.normal;
1953
- collision_vel -= impulse / massA;
1964
+ // Get masses
1965
+ float massA = mass;
1966
+ float massB = max(EPSILON, other.mass);
1954
1967
 
1955
- // Friction
1956
- if (friction > 0.0) {
1957
- vec2 tangent = relativeVel - collision.normal * dot(relativeVel, collision.normal);
1958
- float tangentLength = length(tangent);
1968
+ // Relative velocity
1969
+ vec2 relativeVel = other.velocity - collision_vel;
1970
+ float velocityAlongNormal = dot(relativeVel, collision.normal);
1971
+
1972
+ // Only resolve if moving toward each other
1973
+ if (velocityAlongNormal < 0.0) {
1974
+ // Analytical impulse (symmetric, conserves momentum)
1975
+ float e = clamp(restitution, 0.0, 1.0);
1976
+ float j = -(1.0 + e) * velocityAlongNormal;
1977
+ j /= (1.0 / massA + 1.0 / massB);
1978
+
1979
+ // Apply impulse to THIS object only
1980
+ vec2 impulse = j * collision.normal;
1981
+ collision_vel += impulse / massA; // Note: += because we subtract from relative velocity formula
1959
1982
 
1960
- if (tangentLength > EPSILON) {
1961
- tangent = normalize(tangent);
1962
- float vt = dot(relativeVel, tangent);
1963
-
1964
- float jt = -vt * friction;
1965
- jt /= (1.0 / massA + 1.0 / massB);
1966
-
1967
- // Coulomb friction limit
1968
- float maxFriction = abs(j) * friction;
1969
- jt = clamp(jt, -maxFriction, maxFriction);
1970
-
1971
- vec2 frictionImpulse = jt * tangent;
1972
- collision_vel -= frictionImpulse / massA;
1983
+ // Friction (Coulomb model)
1984
+ vec2 friction_impulse = vec2(0.0);
1985
+ if (friction > 0.0) {
1986
+ vec2 tangent = relativeVel - collision.normal * velocityAlongNormal;
1987
+ float tangentLength = length(tangent);
1988
+ if (tangentLength > EPSILON) {
1989
+ tangent = normalize(tangent);
1990
+ float vt = dot(relativeVel, tangent);
1991
+ float jt = -vt * friction;
1992
+ jt /= (1.0 / massA + 1.0 / massB);
1993
+ // Coulomb limit
1994
+ jt = clamp(jt, -abs(j) * friction, abs(j) * friction);
1995
+ friction_impulse = jt * tangent;
1996
+ collision_vel += friction_impulse / massA;
1997
+ }
1973
1998
  }
1999
+
2000
+ // ================================================================
2001
+ // TORQUE CALCULATION (from contact point)
2002
+ // ================================================================
2003
+ vec2 contactPoint = getContactPoint(p, other, collision.normal, collision.penetration);
2004
+ vec2 r = contactPoint - new_pos; // lever arm from centre to contact
2005
+ float torque_n = r.x * impulse.y - r.y * impulse.x; // cross(r, impulse)
2006
+ float torque_f = r.x * friction_impulse.y - r.y * friction_impulse.x;
2007
+ accumulated_torque += (torque_n + torque_f) / inertia;
1974
2008
  }
1975
- }
1976
-
1977
- // POSITION CORRECTION - only for deep penetrations
1978
- // Move THIS object away from penetration
1979
- const float slop = 0.01;
1980
- const float percent = 0.4; // Less aggressive than before
1981
-
1982
- if (collision.penetration > slop) {
1983
- float totalMass = massA + massB;
1984
- vec2 correction = collision.normal * (collision.penetration - slop) * percent;
1985
2009
 
1986
- // Only correct THIS object's position
1987
- // The correction is weighted by the inverse mass ratio
1988
- new_pos -= correction * (massB / totalMass);
2010
+ // POSITION CORRECTION - mild, to reduce sticking
2011
+ const float slop = 0.05; // larger slop = less aggressive
2012
+ const float percent = 0.2; // smaller percent = softer correction
2013
+ if (collision.penetration > slop) {
2014
+ float totalMass = massA + massB;
2015
+ vec2 correction = collision.normal * (collision.penetration - slop) * percent;
2016
+ // Only correct THIS object's position, weighted by mass ratio
2017
+ new_pos -= correction * (massB / totalMass);
2018
+ }
1989
2019
  }
1990
2020
  }
1991
- }
1992
-
1993
- // Apply collision-modified velocity
1994
- if (had_collision) {
1995
- new_vel = sanitizeVec2(collision_vel);
1996
- }
1997
-
1998
- // ========================================================================
1999
- // REST OF CODE(boundaries, final write, etc.)
2000
- // ========================================================================
2001
2021
 
2002
- // Age out old contacts for this object
2003
- if (uEnableWarmStart == 1) {
2004
- ageContacts(objectIndex);
2022
+ // Apply collision-modified velocity and torque
2023
+ if (had_collision) {
2024
+ new_vel = sanitizeVec2(collision_vel);
2025
+ new_angular_vel += accumulated_torque * uDt;
2005
2026
  }
2006
2027
 
2007
- // REMOVED: The second collision loop that was causing double-resolution
2008
- // We no longer need to check i < objectIndex because all pairs are
2009
- // processed exactly once in the loop above
2010
-
2011
- // Apply the collision-corrected state
2012
- new_pos = sanitizeVec2(new_pos);
2013
- new_vel = sanitizeVec2(new_vel);
2028
+ // Clamp angular velocity for stability
2029
+ const float maxOmega = 100.0;
2030
+ new_angular_vel = clamp(new_angular_vel, -maxOmega, maxOmega);
2031
+ new_rotation = mod(new_rotation, 2.0 * PI);
2014
2032
 
2015
2033
  // ========================================================================
2016
2034
  // FINAL SANITY CHECKS
2017
2035
  // ========================================================================
2036
+ new_pos = sanitizeVec2(new_pos);
2037
+ new_vel = sanitizeVec2(new_vel);
2018
2038
 
2019
2039
  // Ensure velocities aren't excessive
2020
- float maxSpeed = 1000.0;
2040
+ float maxSpeed = 1000000.0;
2021
2041
  float currentSpeed = length(new_vel);
2022
2042
  if (currentSpeed > maxSpeed) {
2023
2043
  new_vel = normalize(new_vel) * maxSpeed;
2024
2044
  }
2025
2045
 
2026
2046
  // ========================================================================
2027
- // WRITE UPDATED OBJECT STATE
2047
+ // WRITE UPDATED OBJECT STATE
2028
2048
  // ========================================================================
2029
2049
  objectsOut[gid].position = new_pos;
2030
2050
  objectsOut[gid].velocity = new_vel;
@@ -2045,8 +2065,4 @@ if (had_collision) {
2045
2065
  objectsOut[gid]._pad1 = 0;
2046
2066
  objectsOut[gid]._padEnd[0] = 0;
2047
2067
  objectsOut[gid]._padEnd[1] = 0;
2048
- }
2049
-
2050
- // ============================================================================
2051
- // END OF RESEARCH-GRADE COLLISION SYSTEM
2052
- // ============================================================================
2068
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: hyperstellar
3
- Version: 0.1.73
3
+ Version: 0.1.74
4
4
  Summary: GPU-accelerated physics simulation engine
5
5
  Author-email: Aiden Jabari <Jabariaiden15@email.com>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "hyperstellar"
7
- version = "0.1.73"
7
+ version = "0.1.74"
8
8
  description = "GPU-accelerated physics simulation engine"
9
9
  readme = "README.md"
10
10
  authors = [{name = "Aiden Jabari", email = "Jabariaiden15@email.com"}]
@@ -72,5 +72,6 @@ where = ["hyperstellar/src"]
72
72
 
73
73
 
74
74
 
75
+
75
76
 
76
77
 
File without changes
File without changes
File without changes