Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added apply_impulse function #741

Merged
merged 1 commit into from
Dec 7, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions ursina/physics.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from panda3d.core import BitMask32, TransformState
from panda3d.bullet import BulletRigidBodyNode, BulletPlaneShape, BulletBoxShape, BulletSphereShape, BulletCapsuleShape, BulletCylinderShape, BulletConeShape, XUp, YUp, ZUp, BulletTriangleMesh, BulletTriangleMeshShape, BulletDebugNode, BulletWorld
from panda3d.bullet import BulletRigidBodyNode, BulletPlaneShape, BulletBoxShape, BulletSphereShape, BulletCylinderShape, BulletCapsuleShape, BulletConeShape, XUp, YUp, ZUp, BulletTriangleMesh, BulletTriangleMeshShape, BulletDebugNode, BulletWorld
from ursina.scripts.property_generator import generate_properties_for_class
from ursina import Entity, scene, time, Vec3

Expand All @@ -23,6 +23,7 @@ def __init__(self):
def update(self):
if self.active:
self.world.doPhysics(time.dt)
# print("physics handler now active")

def debug_setter(self, value):
if value:
Expand All @@ -48,14 +49,14 @@ def __init__(self, center=(0,0,0), radius=.5):
self.center = center
self.radius = radius

class CapsuleShape:
class CylinderShape:
def __init__(self, center=(0,0,0), radius=.5, height=2, axis='y'):
self.center = center
self.radius = radius
self.height = height
self.axis = axis

class CylinderShape:
class CapsuleShape:
def __init__(self, center=(0,0,0), radius=.5, height=2, axis='y'):
self.center = center
self.radius = radius
Expand Down Expand Up @@ -104,8 +105,8 @@ def __init__(self, name: str, world):
self.ignore_paused = False
self.animations = []

def __getattr__(self, attribute):
return getattr(self.node_path.node(), attribute)
def __getattr__(self, attr):
return getattr(self.node_path.node(), attr)


def attach(self):
Expand Down Expand Up @@ -193,10 +194,17 @@ def add_force(self, force, point=(0,0,0)):
else:
self.node_path.node().applyCentralForce(force)

def apply_impulse(self, force, point=(0,0,0)):
self.node_path.node().setActive(True)
if point != (0,0,0):
self.node_path.node().applyImpulse(force, point)
else:
self.node_path.node().applyCentralImpulse(force)


class RigidBody(_PhysicsBody):
def __init__(self, shape, world=physics_handler.world, entity=None, mass=0, kinematic=False, friction=.5, mask=0x1):
if not physics_handler.active and world is physics_handler.world:
if world is physics_handler.world and not physics_handler.active:
physics_handler.active = True
super().__init__(name='RigidBody', world=world)
self.rigid_body_node = BulletRigidBodyNode('RigidBody')
Expand Down Expand Up @@ -233,24 +241,24 @@ def _convert_shape(shape, entity, dynamic=True):
elif isinstance(shape, SphereShape):
return BulletSphereShape(shape.radius)

elif isinstance(shape, CapsuleShape):
elif isinstance(shape, CylinderShape):
if shape.axis == 'y':
axis = YUp
elif shape.axis == 'z':
axis = ZUp
elif shape.axis == 'x':
axis = XUp
return BulletCapsuleShape(shape.radius, shape.height-1, axis)
elif isinstance(shape, CylinderShape):
return BulletCylinderShape(shape.radius, shape.height, axis)

elif isinstance(shape, CapsuleShape):
if shape.axis == 'y':
axis = YUp
elif shape.axis == 'z':
axis = ZUp
elif shape.axis == 'x':
axis = XUp
return BulletCylinderShape(shape.radius, shape.height, axis)
return BulletCapsuleShape(shape.radius, shape.height-1, axis)

elif isinstance(shape, ConeShape):
if shape.axis == 'y':
axis = YUp
Expand Down Expand Up @@ -278,7 +286,7 @@ def _convert_shape(shape, entity, dynamic=True):


if __name__ == '__main__':
from ursina import Ursina, Capsule, Cone, Cylinder, Sequence, Func, curve, Wait, EditorCamera
from ursina import Ursina, Cylinder, Capsule, Cone, Sequence, Func, curve, Wait, EditorCamera

app = Ursina(borderless=False)

Expand All @@ -294,13 +302,13 @@ def _convert_shape(shape, entity, dynamic=True):
sphere = Entity(model='sphere', texture='brick', y=30)
RigidBody(shape=SphereShape(), entity=sphere, mass=5)

capsule = Entity(model=Capsule(height=2, radius=.5), texture='brick', y=17)
RigidBody(shape=CapsuleShape(height=2, radius=.5), entity=capsule, mass=3)

cylinder = Entity(model=Cylinder(height=2, radius=.5, start=-1), texture='brick', y=10)
cylinder = Entity(model=Cylinder(height=2, radius=.5, start=-1), texture='brick', y=17)
RigidBody(shape=CylinderShape(height=2, radius=.5), entity=cylinder, mass=3)

cone = Entity(model=Cone(8, height=2, radius=.5), texture='brick', y=15)
capsule = Entity(model=Capsule(height=2, radius=.5), texture='brick', y=15)
RigidBody(shape=CapsuleShape(height=2, radius=.5), entity=capsule, mass=3)

cone = Entity(model=Cone(resolution=8, height=2, radius=.5), texture='brick', y=13)
RigidBody(shape=ConeShape(height=2, radius=.5), entity=cone, mass=2)

platform = Entity(model='cube', texture='white_cube', y=1, scale=(4,1,4))
Expand All @@ -310,19 +318,21 @@ def _convert_shape(shape, entity, dynamic=True):
path = [Vec3(-2,1,-2), Vec3(2,1,-2), Vec3(0, 1, 2)]
travel_time = 2
for target_pos in path:
platform_sequence.append(Func(platform_body.animate_position, value=target_pos, duration=travel_time, curve=curve.linear))
platform_sequence.append(Wait(travel_time))
platform_sequence.append(Func(platform_body.animate_position, value=target_pos, duration=travel_time, curve=curve.linear), regenerate=False)
platform_sequence.append(Wait(travel_time), regenerate=False)
platform_sequence.generate()
platform_sequence.start()


def input(key):
if key == 'space up':
e = Entity(model='cube', texture='white_cube', y=7)
RigidBody(shape=BoxShape(), entity=e, mass=1, friction=1)
if key == 'up arrow':
cube_body.add_force(force=Vec3(0, 1000, 0), point=Vec3(0,0,0))
print('force applied')
cube_body.apply_impulse(force=Vec3(0, 10, 0), point=Vec3(0,0,0))
print('impulse applied')

physics_handler.debug = True

EditorCamera()
app.run()
app.run()
Loading