Additional Ruby Bindings for Collision Functions

Share your projects and Chipmunk enhancements.
Post Reply
norman
Posts: 1
Joined: Thu Nov 08, 2007 4:05 pm
Contact:

Additional Ruby Bindings for Collision Functions

Post by norman »

Hi,
here's a patch to make chipmunk send the contacts objects into the collision function blocks.

Any thoughts or improvements, let me know.
-Tom Lea

Example Usage:

Code: Select all

    #@space.add_collision_func(:player,:block) do |player, block| # <= Old code
    @space.add_collision_func(:player,:block) do |player, block, collisions| # <= New Code
          collisions.each do {|c| puts "p=#{c.p}, n=#{c.n}, dist=#{c.dist}"} 
    end
Unified Patch

Code: Select all

diff -Naur ../../Chipmunk-4.0.1/ruby/rb_chipmunk.c ./rb_chipmunk.c
--- ../../Chipmunk-4.0.1/ruby/rb_chipmunk.c	2007-08-29 07:38:34.000000000 +0100
+++ ./rb_chipmunk.c	2007-10-31 23:57:59.000000000 +0000
@@ -106,4 +106,5 @@
 	Init_cpShape();
 	Init_cpJoint();
 	Init_cpSpace();
+	Init_cpContact();
 }
diff -Naur ../../Chipmunk-4.0.1/ruby/rb_chipmunk.h ./rb_chipmunk.h
--- ../../Chipmunk-4.0.1/ruby/rb_chipmunk.h	2007-07-01 20:27:57.000000000 +0100
+++ ./rb_chipmunk.h	2007-11-08 19:54:27.000000000 +0000
@@ -30,6 +30,7 @@
 extern VALUE c_cpPolyShape;
 extern VALUE m_cpJoint;
 extern VALUE c_cpSpace;
+extern VALUE c_cpContact;
 
 extern ID id_parent;
 
@@ -41,6 +42,16 @@
 	return Data_Wrap_Struct(c_cpVect, NULL, &free, ptr);	
 }
 
+// We must ensure we null the contact reference after the callback is done.
+static inline VALUE
+CONTACTNEW(cpContact * v)
+{
+	cpContact * new_v = (cpContact *)malloc(sizeof(cpContact));
+	memcpy(new_v, v, sizeof(cpContact));
+	return Data_Wrap_Struct(c_cpContact, NULL, &free, new_v);
+}
+
+
 //static inline VALUE
 //VWRAP(cpVect *v, VALUE parent)
 //{
@@ -67,6 +78,7 @@
 GETTER_TEMPLATE(SHAPE, m_cpShape, Shape, cpShape)
 GETTER_TEMPLATE(JOINT, m_cpJoint, Joint, cpJoint)
 GETTER_TEMPLATE(SPACE, c_cpSpace, Space, cpSpace)
+GETTER_TEMPLATE(CONTACT, c_cpContact, Space, cpContact)
 
 void Init_chipmunk(void);
 void Init_cpVect();
@@ -75,3 +87,4 @@
 void Init_cpShape();
 void Init_cpJoint();
 void Init_cpSpace();
+void Init_cpContact();
diff -Naur ../../Chipmunk-4.0.1/ruby/rb_cpContact.c ./rb_cpContact.c
--- ../../Chipmunk-4.0.1/ruby/rb_cpContact.c	1970-01-01 01:00:00.000000000 +0100
+++ ./rb_cpContact.c	2007-11-08 21:10:14.000000000 +0000
@@ -0,0 +1,158 @@
+#include "chipmunk.h"
+
+#include "ruby.h"
+#include "rb_chipmunk.h"
+
+VALUE c_cpContact;
+
+static VALUE
+rb_cpContactGetp(VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return VNEW(CONTACT(self)->p);
+}
+
+static VALUE
+rb_cpContactGetn(VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return VNEW(CONTACT(self)->n);
+}
+
+static VALUE
+rb_cpContactGetr1(VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return VNEW(CONTACT(self)->r1);
+}
+
+static VALUE
+rb_cpContactGetr2(VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return VNEW(CONTACT(self)->r2);
+}
+
+static VALUE
+rb_cpContactGetdist(VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return rb_float_new(CONTACT(self)->dist);
+}
+
+static VALUE
+rb_cpContactGetnMass(VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return rb_float_new(CONTACT(self)->nMass);
+}
+
+static VALUE
+rb_cpContactGettMass(VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return rb_float_new(CONTACT(self)->tMass);
+}
+
+static VALUE
+rb_cpContactGetbounce(VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return rb_float_new(CONTACT(self)->bounce);
+}
+
+static VALUE
+rb_cpContactGetjnAcc (VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return rb_float_new(CONTACT(self)->jnAcc);
+}
+
+static VALUE
+rb_cpContactGetjtAcc (VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return rb_float_new(CONTACT(self)->jtAcc);
+}
+
+static VALUE
+rb_cpContactGetjBias (VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return rb_float_new(CONTACT(self)->jBias);
+}
+
+static VALUE
+rb_cpContactGetbias (VALUE self)
+{
+	if(!CONTACT(self))
+	{
+		rb_raise(rb_eArgError, "Contact gone.");
+		return Qnil;
+	}
+	return rb_float_new(CONTACT(self)->bias);
+}
+
+
+void
+Init_cpContact(void)
+{
+	c_cpContact = rb_define_class_under(m_Chipmunk, "Contact", rb_cObject);
+	
+	rb_define_method(c_cpContact, "p", rb_cpContactGetp, 0);
+	rb_define_method(c_cpContact, "n", rb_cpContactGetn, 0);
+	rb_define_method(c_cpContact, "dist", rb_cpContactGetdist, 0);
+	rb_define_method(c_cpContact, "r1", rb_cpContactGetr1, 0);
+	rb_define_method(c_cpContact, "r2", rb_cpContactGetr2, 0);
+	rb_define_method(c_cpContact, "nMass", rb_cpContactGetnMass, 0);
+	rb_define_method(c_cpContact, "tMass", rb_cpContactGettMass, 0);
+	rb_define_method(c_cpContact, "bounce", rb_cpContactGetbounce, 0);
+	rb_define_method(c_cpContact, "jnAcc", rb_cpContactGetjnAcc, 0);
+	rb_define_method(c_cpContact, "jtAcc", rb_cpContactGetjtAcc, 0);
+	rb_define_method(c_cpContact, "jBias", rb_cpContactGetjBias, 0);
+	rb_define_method(c_cpContact, "bias", rb_cpContactGetbias, 0);
+}
diff -Naur ../../Chipmunk-4.0.1/ruby/rb_cpSpace.c ./rb_cpSpace.c
--- ../../Chipmunk-4.0.1/ruby/rb_cpSpace.c	2007-09-01 19:53:04.000000000 +0100
+++ ./rb_cpSpace.c	2007-11-08 21:09:55.000000000 +0000
@@ -97,8 +97,14 @@
 	VALUE block = (VALUE)data;
 	VALUE shapea = (VALUE)a->data;
 	VALUE shapeb = (VALUE)b->data;
+	VALUE rb_contact_array = rb_ary_new();
 	
-	return rb_funcall(block, id_call, 2, shapea, shapeb);
+	for(int i = 0; i < numContacts; i++)
+		rb_ary_push(rb_contact_array, CONTACTNEW(&contacts[i]));
+	
+	int rv = rb_funcall(block, id_call, 3, shapea, shapeb, rb_contact_array);
+			
+	return rv;
 }
 
 static VALUE
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests