Commits

German Larrain committed 8e78dd5

model.simulator: 'physics' and 'collision' modules are now packages, in the same directory as 'simulator'

  • Participants
  • Parent commits 0171d9e
  • Branches dev-collision-engine

Comments (0)

Files changed (7)

ars/model/collision/__init__.py

Empty file added.

ars/model/collision/base.py

+
+# Created on 2011.10.31
+#
+# @author: german
+
+import ode
+
+import ars.model.geometry.base as shapes
+
+class Engine:
+	pass
+
+class Space:
+	def __init__(self):
+		self._inner_object = ode.SimpleSpace() # same as ode.Space(space_type=0)
+
+	def get_inner_object(self):
+		return self._inner_object
+
+	def collide(self, args, callback):
+		self._inner_object.collide(args, callback)
+	
+	#===========================================================================
+	# def add_ray(self, position, direction):
+	#	"""Adds a ray to the space, whose `_inner_object` will store it"""
+	#	shapes.Ray(self, position, direction) # no need for assignment
+	#===========================================================================
+
+class RayContact:
+	"""Contact information of a collision between a ray and a shape"""
+	
+	def __init__(self, ray=None, shape=None, position=None, normal=None, depth=None):
+		self._ray = ray
+		self._shape = shape
+		self._position = position # point at which the ray intersects the surface of the other geom
+		self._normal = normal # surface normal of the other geom at the contact point
+		self._depth = depth # distance from the start of the ray to the contact point
+
+class NearCallbackArgs:
+	"""Class to encapsulate args passed to the `near_callback` function"""
+	
+	def __init__(self, world=None, contact_group=None, ignore_connected=True):
+		self.world = world
+		self.contact_group = contact_group
+		self.ignore_connected = ignore_connected
+
+def near_callback(args, geom1, geom2):
+	"""Callback function for the collide() method (in ODE). This function
+	checks if the given geoms do collide and creates contact joints (c_joint)
+	if they do, except if they are connected."""
+	
+	c_joint_bounce = 0.2 # default: 0.2
+	c_joint_mu = 500 # default: 500. 0-5 = very slippery, 50-500 = normal, 5000 = very sticky
+
+	if args.ignore_connected:
+		if (ode.areConnected(geom1.getBody(), geom2.getBody())):
+			return
+
+	#===========================================================================
+	# create contact joints
+	#===========================================================================
+	#world, contact_group = args
+	world = args.world
+	contact_group = args.contact_group
+
+	# check if the objects collide
+	contacts = ode.collide(geom1, geom2)
+	for c in contacts:
+		c.setBounce(c_joint_bounce)
+		c.setMu(c_joint_mu)
+		j = ode.ContactJoint(world, contact_group, c)
+		j.attach(geom1.getBody(), geom2.getBody())

ars/model/physics/__init__.py

Empty file added.

ars/model/physics/base.py

+
+# Created on 2011.08.09
+#
+# @author: german
+
+from abc import ABCMeta, abstractmethod
+
+import ode
+
+import ars.model.geometry.base as shapes
+
+class Engine:
+	pass
+
+class Body:
+	__metaclass__ = ABCMeta
+
+	@abstractmethod
+	def __init__(self):
+		self._inner_object = None
+		self._attached_geom = None
+
+	def attach_geom(self, geom):
+		geom.attach_body(self)
+		self._attached_geom = geom
+
+#===============================================================================
+# GETTERS AND SETTERS
+#===============================================================================
+
+	def get_inner_object(self):
+		return self._inner_object
+
+	def get_attached_geom(self):
+		return self._attached_geom
+
+	def get_position(self):
+		return self._inner_object.getPosition()
+
+	def get_linear_velocity(self):
+		return self._inner_object.getLinearVel()
+
+	def get_rotation(self):
+		return self._inner_object.getRotation()
+
+	def get_angular_velocity(self):
+		return self._inner_object.getAngularVel()
+
+	def get_mass(self):
+		return self._inner_object.getMass().mass
+
+	def get_center_of_gravity(self):
+		return self._inner_object.getMass().c
+
+	def get_inertia_tensor(self):
+		return self._inner_object.getMass().I
+
+	def set_position(self, pos):
+		self._inner_object.setPosition(pos)
+
+	def set_rotation(self, rot):
+		self._inner_object.setRotation(rot)
+
+class Capsule(Body):
+	def __init__(self, world, space, length, radius, mass=None, density=None):
+		"""create capsule body (aligned along the z-axis so that it matches the
+		Geom created below,	which is aligned along the Z-axis by default)"""
+
+		if mass is not None:
+			if density is not None:
+				raise Exception('Both mass and density arguments were given')
+
+		self._length = length
+		self._radius = radius
+
+		body = _create_ode_capsule(world, space, length, radius, mass, density)
+		geom = shapes.Capsule(space, length, radius)
+		self._inner_object = body
+		self.attach_geom(geom)
+
+	def get_length(self):
+		return self._length
+
+	def get_radius(self):
+		return self._radius
+
+class Cylinder(Body):
+
+	def __init__(self, world, space, length, radius, mass=None, density=None):
+		"""create cylinder body (aligned along the z-axis so that it matches
+		the Geom created below,	which is aligned along the Z-axis by default)"""
+
+		if mass is not None:
+			if density is not None:
+				raise Exception('Both mass and density arguments were given')
+
+		self._length = length
+		self._radius = radius
+
+		body = _create_ode_cylinder(world, space, length, radius, mass, density)
+		geom = shapes.Cylinder(space, length, radius)
+		self._inner_object = body
+		self.attach_geom(geom)
+
+	def get_length(self):
+		return self._length
+
+	def get_radius(self):
+		return self._radius
+
+class Box(Body):
+	def __init__(self, world, space, size, mass=None, density=None):
+
+		if mass is not None:
+			if density is not None:
+				raise Exception('Both mass and density arguments were given')
+
+		self._size = size
+
+		body = _create_ode_box(world, space, size, mass, density)
+		geom = shapes.Box(space, size)
+		self._inner_object = body
+		self.attach_geom(geom)
+
+	def get_size(self):
+		return self._size
+
+class Sphere(Body):
+	def __init__(self, world, space, radius, mass=None, density=None):
+
+		if mass is not None:
+			if density is not None:
+				return Exception('Both mass and density arguments were given')
+
+		self._radius = radius
+
+		body = _create_ode_sphere(world, space, radius, mass, density)
+		geom = shapes.Sphere(space, radius)
+		self._inner_object = body
+		self.attach_geom(geom)
+
+	def get_radius(self):
+		return self._radius
+
+class Cone(Body):
+	def __init__(self, world, space, height, radius, mass=None, density=None):
+		raise Exception("Not available in ODE")
+
+def create_world(gravity=(0.0,-9.81,0.0), ERP=0.8, CFM=1E-10):
+	"""Create an ODE world object"""
+	world = ode.World()
+	world.setGravity(gravity)
+	world.setERP(ERP)
+	world.setCFM(CFM)
+	return world
+
+def _create_ode_capsule(world, space, length, radius, mass=None, density=None):
+
+	capsule_direction = 3 # z-axis
+	body = ode.Body(world)
+
+	if mass is not None:
+		m = ode.Mass()
+		m.setCappedCylinderTotal(mass, capsule_direction, radius, length)
+		body.setMass(m)
+	elif density is not None:
+		m = ode.Mass()
+		m.setCappedCylinder(density, capsule_direction, radius, length)
+		body.setMass(m)
+
+	# set parameters for drawing the body
+	body.shape = "capsule" # TODO: delete this, because it is related to the original implementation
+	body.length = length
+	body.radius = radius
+
+	return body
+
+def _create_ode_cylinder(world, space, length, radius, mass=None, density=None):
+	cylinderDirection = 3 # Z-axis
+	body = ode.Body(world)
+
+	if mass is not None:
+		m = ode.Mass()
+		m.setCylinderTotal(mass, cylinderDirection, radius, length)
+		body.setMass(m)
+	elif density is not None:
+		m = ode.Mass()
+		m.setCylinder(density, cylinderDirection, radius, length)
+		body.setMass(m)
+
+	return body
+
+def _create_ode_box(world, space, size, mass=None, density=None):
+	body = ode.Body(world)
+
+	if mass is not None:
+		m = ode.Mass()
+		m.setBoxTotal(mass, *size)
+		body.setMass(m)
+	elif density is not None:
+		m = ode.Mass()
+		m.setBox(density, *size)
+		body.setMass(m)
+
+	return body
+
+def _create_ode_sphere(world, space, radius, mass=None, density=None):
+	body = ode.Body(world)
+
+	if mass is not None:
+		m = ode.Mass()
+		m.setSphereTotal(mass, radius)
+		body.setMass(m)
+	elif density is not None:
+		m = ode.Mass()
+		m.setSphere(density, radius)
+		body.setMass(m)
+
+	return body
+
+def create_joint_group():
+	return ode.JointGroup()
+
+def create_plane_geom(space, normal, dist):
+	return ode.GeomPlane(space.get_inner_object(), normal, dist)

ars/model/simulator/__init__.py

 import ars.utilities.generic as gu
 import ars.utilities.mathematical as mu
 
-import collision as coll
-import physics as phs
+import ars.model.collision.base as coll
+import ars.model.physics.base as phs
 
 class Simulation:
 

ars/model/simulator/collision.py

-
-# Created on 2011.10.31
-#
-# @author: german
-
-import ode
-
-import ars.model.geometry.base as shapes
-
-class Engine:
-	pass
-
-class Space:
-	def __init__(self):
-		self._inner_object = ode.SimpleSpace() # same as ode.Space(space_type=0)
-
-	def get_inner_object(self):
-		return self._inner_object
-
-	def collide(self, args, callback):
-		self._inner_object.collide(args, callback)
-	
-	#===========================================================================
-	# def add_ray(self, position, direction):
-	#	"""Adds a ray to the space, whose `_inner_object` will store it"""
-	#	shapes.Ray(self, position, direction) # no need for assignment
-	#===========================================================================
-
-class RayContact:
-	"""Contact information of a collision between a ray and a shape"""
-	
-	def __init__(self, ray=None, shape=None, position=None, normal=None, depth=None):
-		self._ray = ray
-		self._shape = shape
-		self._position = position # point at which the ray intersects the surface of the other geom
-		self._normal = normal # surface normal of the other geom at the contact point
-		self._depth = depth # distance from the start of the ray to the contact point
-
-class NearCallbackArgs:
-	"""Class to encapsulate args passed to the `near_callback` function"""
-	
-	def __init__(self, world=None, contact_group=None, ignore_connected=True):
-		self.world = world
-		self.contact_group = contact_group
-		self.ignore_connected = ignore_connected
-
-def near_callback(args, geom1, geom2):
-	"""Callback function for the collide() method (in ODE). This function
-	checks if the given geoms do collide and creates contact joints (c_joint)
-	if they do, except if they are connected."""
-	
-	c_joint_bounce = 0.2 # default: 0.2
-	c_joint_mu = 500 # default: 500. 0-5 = very slippery, 50-500 = normal, 5000 = very sticky
-
-	if args.ignore_connected:
-		if (ode.areConnected(geom1.getBody(), geom2.getBody())):
-			return
-
-	#===========================================================================
-	# create contact joints
-	#===========================================================================
-	#world, contact_group = args
-	world = args.world
-	contact_group = args.contact_group
-
-	# check if the objects collide
-	contacts = ode.collide(geom1, geom2)
-	for c in contacts:
-		c.setBounce(c_joint_bounce)
-		c.setMu(c_joint_mu)
-		j = ode.ContactJoint(world, contact_group, c)
-		j.attach(geom1.getBody(), geom2.getBody())

ars/model/simulator/physics.py

-
-# Created on 2011.08.09
-#
-# @author: german
-
-from abc import ABCMeta, abstractmethod
-
-import ode
-
-import ars.model.geometry.base as shapes
-
-class Engine:
-	pass
-
-class Body:
-	__metaclass__ = ABCMeta
-
-	@abstractmethod
-	def __init__(self):
-		self._inner_object = None
-		self._attached_geom = None
-
-	def attach_geom(self, geom):
-		geom.attach_body(self)
-		self._attached_geom = geom
-
-#===============================================================================
-# GETTERS AND SETTERS
-#===============================================================================
-
-	def get_inner_object(self):
-		return self._inner_object
-
-	def get_attached_geom(self):
-		return self._attached_geom
-
-	def get_position(self):
-		return self._inner_object.getPosition()
-
-	def get_linear_velocity(self):
-		return self._inner_object.getLinearVel()
-
-	def get_rotation(self):
-		return self._inner_object.getRotation()
-
-	def get_angular_velocity(self):
-		return self._inner_object.getAngularVel()
-
-	def get_mass(self):
-		return self._inner_object.getMass().mass
-
-	def get_center_of_gravity(self):
-		return self._inner_object.getMass().c
-
-	def get_inertia_tensor(self):
-		return self._inner_object.getMass().I
-
-	def set_position(self, pos):
-		self._inner_object.setPosition(pos)
-
-	def set_rotation(self, rot):
-		self._inner_object.setRotation(rot)
-
-class Capsule(Body):
-	def __init__(self, world, space, length, radius, mass=None, density=None):
-		"""create capsule body (aligned along the z-axis so that it matches the
-		Geom created below,	which is aligned along the Z-axis by default)"""
-
-		if mass is not None:
-			if density is not None:
-				raise Exception('Both mass and density arguments were given')
-
-		self._length = length
-		self._radius = radius
-
-		body = _create_ode_capsule(world, space, length, radius, mass, density)
-		geom = shapes.Capsule(space, length, radius)
-		self._inner_object = body
-		self.attach_geom(geom)
-
-	def get_length(self):
-		return self._length
-
-	def get_radius(self):
-		return self._radius
-
-class Cylinder(Body):
-
-	def __init__(self, world, space, length, radius, mass=None, density=None):
-		"""create cylinder body (aligned along the z-axis so that it matches
-		the Geom created below,	which is aligned along the Z-axis by default)"""
-
-		if mass is not None:
-			if density is not None:
-				raise Exception('Both mass and density arguments were given')
-
-		self._length = length
-		self._radius = radius
-
-		body = _create_ode_cylinder(world, space, length, radius, mass, density)
-		geom = shapes.Cylinder(space, length, radius)
-		self._inner_object = body
-		self.attach_geom(geom)
-
-	def get_length(self):
-		return self._length
-
-	def get_radius(self):
-		return self._radius
-
-class Box(Body):
-	def __init__(self, world, space, size, mass=None, density=None):
-
-		if mass is not None:
-			if density is not None:
-				raise Exception('Both mass and density arguments were given')
-
-		self._size = size
-
-		body = _create_ode_box(world, space, size, mass, density)
-		geom = shapes.Box(space, size)
-		self._inner_object = body
-		self.attach_geom(geom)
-
-	def get_size(self):
-		return self._size
-
-class Sphere(Body):
-	def __init__(self, world, space, radius, mass=None, density=None):
-
-		if mass is not None:
-			if density is not None:
-				return Exception('Both mass and density arguments were given')
-
-		self._radius = radius
-
-		body = _create_ode_sphere(world, space, radius, mass, density)
-		geom = shapes.Sphere(space, radius)
-		self._inner_object = body
-		self.attach_geom(geom)
-
-	def get_radius(self):
-		return self._radius
-
-class Cone(Body):
-	def __init__(self, world, space, height, radius, mass=None, density=None):
-		raise Exception("Not available in ODE")
-
-def create_world(gravity=(0.0,-9.81,0.0), ERP=0.8, CFM=1E-10):
-	"""Create an ODE world object"""
-	world = ode.World()
-	world.setGravity(gravity)
-	world.setERP(ERP)
-	world.setCFM(CFM)
-	return world
-
-def _create_ode_capsule(world, space, length, radius, mass=None, density=None):
-
-	capsule_direction = 3 # z-axis
-	body = ode.Body(world)
-
-	if mass is not None:
-		m = ode.Mass()
-		m.setCappedCylinderTotal(mass, capsule_direction, radius, length)
-		body.setMass(m)
-	elif density is not None:
-		m = ode.Mass()
-		m.setCappedCylinder(density, capsule_direction, radius, length)
-		body.setMass(m)
-
-	# set parameters for drawing the body
-	body.shape = "capsule" # TODO: delete this, because it is related to the original implementation
-	body.length = length
-	body.radius = radius
-
-	return body
-
-def _create_ode_cylinder(world, space, length, radius, mass=None, density=None):
-	cylinderDirection = 3 # Z-axis
-	body = ode.Body(world)
-
-	if mass is not None:
-		m = ode.Mass()
-		m.setCylinderTotal(mass, cylinderDirection, radius, length)
-		body.setMass(m)
-	elif density is not None:
-		m = ode.Mass()
-		m.setCylinder(density, cylinderDirection, radius, length)
-		body.setMass(m)
-
-	return body
-
-def _create_ode_box(world, space, size, mass=None, density=None):
-	body = ode.Body(world)
-
-	if mass is not None:
-		m = ode.Mass()
-		m.setBoxTotal(mass, *size)
-		body.setMass(m)
-	elif density is not None:
-		m = ode.Mass()
-		m.setBox(density, *size)
-		body.setMass(m)
-
-	return body
-
-def _create_ode_sphere(world, space, radius, mass=None, density=None):
-	body = ode.Body(world)
-
-	if mass is not None:
-		m = ode.Mass()
-		m.setSphereTotal(mass, radius)
-		body.setMass(m)
-	elif density is not None:
-		m = ode.Mass()
-		m.setSphere(density, radius)
-		body.setMass(m)
-
-	return body
-
-def create_joint_group():
-	return ode.JointGroup()
-
-def create_plane_geom(space, normal, dist):
-	return ode.GeomPlane(space.get_inner_object(), normal, dist)