1 //metadoc ODEJointGroup copyright Jonathan Wright, 2006
2 //metadoc ODEJointGroup license BSD revised
3 /*metadoc ODEJointGroup description
7 #include "IoODEJointGroup.h"
8 #include "IoODEJoint.h"
9 #include "IoODEContact.h"
13 #include "IoODEBall.h"
14 #include "IoODEHinge.h"
15 #include "IoODESlider.h"
16 #include "IoODEHinge2.h"
17 #include "IoODEUniversal.h"
18 #include "IoODEFixed.h"
19 //#include "IoODEAMotor.h"
20 //#include "IoODELMotor.h"
21 #include "IoODEContactJoint.h"
23 #define DATA(self) ((IoODEJointGroupData *)IoObject_dataPointer(self))
24 #define JOINTGROUPID (DATA(self)->jointGroupId)
25 #define WORLD (DATA(self)->world)
26 #define WORLDID (IoODEWorld_rawWorldId(WORLD))
29 IoTag
*IoODEJointGroup_newTag(void *state
)
31 IoTag
*tag
= IoTag_newWithName_("ODEJointGroup");
32 IoTag_state_(tag
, state
);
33 IoTag_freeFunc_(tag
, (IoTagFreeFunc
*)IoODEJointGroup_free
);
34 IoTag_markFunc_(tag
, (IoTagMarkFunc
*)IoODEJointGroup_mark
);
35 IoTag_cloneFunc_(tag
, (IoTagCloneFunc
*)IoODEJointGroup_rawClone
);
39 IoODEJointGroup
*IoODEJointGroup_proto(void *state
)
41 IoObject
*self
= IoObject_new(state
);
42 IoObject_tag_(self
, IoODEJointGroup_newTag(state
));
44 IoObject_setDataPointer_(self
, calloc(1, sizeof(IoODEJointGroupData
)));
48 DATA(self
)->joints
= 0L;
50 IoState_registerProtoWithFunc_(state
, self
, IoODEJointGroup_proto
);
53 IoMethodTable methodTable
[] = {
54 {"jointGroupId", IoODEJointGroup_jointGroupId
},
55 {"world", IoODEJointGroup_world
},
56 {"empty", IoODEJointGroup_empty
},
57 {"joints", IoODEJointGroup_joints
},
58 {"createContact", IoODEJointGroup_createContact
},
61 IoObject_addMethodTable_(self
, methodTable
);
66 IoODEJointGroup
*IoODEJointGroup_rawClone(IoODEJointGroup
*proto
)
68 IoObject
*self
= IoObject_rawClonePrimitive(proto
);
69 IoObject_setDataPointer_(self
, calloc(1, sizeof(IoODEJointGroupData
)));
71 if(DATA(proto
)->world
)
73 IoODEWorld
*world
= DATA(proto
)->world
;
75 IoODEWorld_addJointGroup(world
, self
);
76 JOINTGROUPID
= dJointGroupCreate(0);
77 DATA(self
)->joints
= List_new();
79 IoObject_inlineSetSlot_to_(self
, IOSYMBOL("Ball"), IoODEBall_newProto(IOSTATE
, self
));
80 IoObject_inlineSetSlot_to_(self
, IOSYMBOL("Hinge"), IoODEHinge_newProto(IOSTATE
, self
));
81 IoObject_inlineSetSlot_to_(self
, IOSYMBOL("Slider"), IoODESlider_newProto(IOSTATE
, self
));
82 IoObject_inlineSetSlot_to_(self
, IOSYMBOL("Hinge2"), IoODEHinge2_newProto(IOSTATE
, self
));
83 IoObject_inlineSetSlot_to_(self
, IOSYMBOL("Universal"), IoODEUniversal_newProto(IOSTATE
, self
));
84 IoObject_inlineSetSlot_to_(self
, IOSYMBOL("Fixed"), IoODEFixed_newProto(IOSTATE
, self
));
85 //IoObject_inlineSetSlot_to_(self, IOSYMBOL("AMotor"), IoODEAMotor_newProto(IOSTATE, self));
86 //IoObject_inlineSetSlot_to_(self, IOSYMBOL("LMotor"), IoODELMotor_newProto(IOSTATE, self));
91 void IoODEJointGroup_free(IoODEJointGroup
*self
)
93 if(JOINTGROUPID
&& WORLD
)
95 IoODEWorld_removeJointGroup(WORLD
, self
);
96 dJointGroupDestroy(JOINTGROUPID
);
98 if(DATA(self
)->joints
)
100 LIST_FOREACH(DATA(self
)->joints
, i
, joint
,
101 IoODEJoint_worldDestoryed((IoODEJoint
*)joint
);
103 List_free(DATA(self
)->joints
);
105 free(IoObject_dataPointer(self
));
108 void IoODEJointGroup_mark(IoODEJointGroup
*self
)
112 IoObject_shouldMark((IoObject
*)WORLD
);
114 if(DATA(self
)->joints
)
116 LIST_FOREACH(DATA(self
)->joints
, i
, joint
,
117 IoObject_shouldMark(joint
);
122 IoODEJointGroup
*IoODEJointGroup_new(void *state
)
124 IoODEJointGroup
*proto
= IoState_protoWithInitFunction_(state
, IoODEJointGroup_proto
);
125 return IOCLONE(proto
);
128 IoODEJointGroup
*IoODEJointGroup_newJointGroupProtoWithWorld(void *state
, IoODEWorld
*world
)
130 IoODEJointGroup
*proto
= IoState_protoWithInitFunction_(state
, IoODEJointGroup_proto
);
131 IoODEJointGroup
*self
= IOCLONE(proto
);
137 /* ----------------------------------------------------------- */
139 void IoODEJointGroup_worldDestoryed(IoODEJointGroup
*self
)
143 if(DATA(self
)->joints
)
145 LIST_FOREACH(DATA(self
)->joints
, i
, joint
,
146 IoODEJoint_worldDestoryed((IoODEJoint
*)joint
);
148 List_free(DATA(self
)->joints
);
149 DATA(self
)->joints
= 0L;
153 void IoODEJointGroup_rawEmpty(IoODEJointGroup
*self
)
155 dJointGroupEmpty(JOINTGROUPID
);
157 LIST_FOREACH(DATA(self
)->joints
, i
, joint
,
158 IoODEJoint_worldDestoryed((IoODEJoint
*)joint
);
160 List_removeAll(DATA(self
)->joints
);
163 dJointGroupID
IoODEJointGroup_rawJointGroupId(IoODEJointGroup
*self
)
168 dWorldID
IoODEJointGroup_rawWorldId(IoODEJointGroup
*self
)
173 void IoODEJointGroup_addJoint(IoODEJointGroup
*self
, IoODEJoint
*joint
)
175 List_append_(DATA(self
)->joints
, joint
);
178 void IoODEJointGroup_removeJoint(IoODEJointGroup
*self
, IoODEJoint
*joint
)
180 List_remove_(DATA(self
)->joints
, joint
);
184 /* ----------------------------------------------------------- */
186 void IoODEJointGroup_assertValidJointGroup(IoODEJointGroup
*self
, IoObject
*locals
, IoMessage
*m
)
188 IOASSERT(WORLD
, "This ODE JointGroup belongs to an ODE world which has been freed.");
189 IOASSERT(JOINTGROUPID
, "ODE World JointGroup cannot be used directly. Clone the world and use the JointGroup on the cloned world.");
193 IoObject
*IoODEJointGroup_jointGroupId(IoODEJointGroup
*self
, IoObject
*locals
, IoMessage
*m
)
195 return IONUMBER((long)JOINTGROUPID
);
198 IoObject
*IoODEJointGroup_world(IoODEJointGroup
*self
, IoObject
*locals
, IoMessage
*m
)
200 return WORLD
? WORLD
: IONIL(self
);
203 IoObject
*IoODEJointGroup_empty(IoODEJointGroup
*self
, IoObject
*locals
, IoMessage
*m
)
205 IoODEJointGroup_assertValidJointGroup(self
, locals
, m
);
206 IoODEJointGroup_rawEmpty(self
);
210 IoObject
*IoODEJointGroup_joints(IoODEWorld
*self
, IoObject
*locals
, IoMessage
*m
)
212 IoODEJointGroup_assertValidJointGroup(self
, locals
, m
);
214 IoList
*list
= IoList_new(IOSTATE
);
215 IoList_rawAddBaseList_(list
, DATA(self
)->joints
);
220 IoObject
*IoODEJointGroup_createContact(IoODEWorld
*self
, IoObject
*locals
, IoMessage
*m
)
222 dContact
*contact
= IoMessage_locals_odeContactStructArgAt_(m
, locals
, 0);
225 IoODEJointGroup_assertValidJointGroup(self
, locals
, m
);
227 jointId
= dJointCreateContact (WORLDID
, JOINTGROUPID
, contact
);
229 return IoODEContactJoint_new(IOSTATE
, self
, jointId
);