1 //metadoc ODESimpleSpace copyright Jonathan Wright, 2006
2 //metadoc ODESimpleSpace license BSD revised
3 /*metadoc ODESimpleSpace description
7 #include "IoODESimpleSpace.h"
8 #include "IoODEPlane.h"
10 #include "IoODEBody.h"
14 #include "IoMessage.h"
17 #define DATA(self) ((IoODESimpleSpaceData *)IoObject_dataPointer(self))
18 #define SPACEID (DATA(self)->spaceId)
20 IoTag
*IoODESimpleSpace_newTag(void *state
)
22 IoTag
*tag
= IoTag_newWithName_("ODESimpleSpace");
23 IoTag_state_(tag
, state
);
24 IoTag_freeFunc_(tag
, (IoTagFreeFunc
*)IoODESimpleSpace_free
);
25 IoTag_cloneFunc_(tag
, (IoTagCloneFunc
*)IoODESimpleSpace_rawClone
);
29 IoODESimpleSpace
*IoODESimpleSpace_proto(void *state
)
31 IoObject
*self
= IoObject_new(state
);
32 IoObject_tag_(self
, IoODESimpleSpace_newTag(state
));
34 IoObject_setDataPointer_(self
, calloc(1, sizeof(IoODESimpleSpaceData
)));
38 IoState_registerProtoWithFunc_(state
, self
, IoODESimpleSpace_proto
);
41 IoMethodTable methodTable
[] = {
42 {"spaceId", IoODESimpleSpace_spaceId
},
43 {"collide", IoODESimpleSpace_collide
},
45 {"plane", IoODESimpleSpace_plane
},
46 {"box", IoODESimpleSpace_box
},
50 IoObject_addMethodTable_(self
, methodTable
);
55 IoODESimpleSpace
*IoODESimpleSpace_rawClone(IoODESimpleSpace
*proto
)
57 IoObject
*self
= IoObject_rawClonePrimitive(proto
);
58 IoObject_setDataPointer_(self
, calloc(1, sizeof(IoODESimpleSpaceData
)));
59 SPACEID
= dSimpleSpaceCreate(0);
60 dSpaceSetCleanup(SPACEID
, 0);
64 IoODESimpleSpace
*IoODESimpleSpace_new(void *state
)
66 IoODESimpleSpace
*proto
= IoState_protoWithInitFunction_(state
, IoODESimpleSpace_proto
);
67 return IOCLONE(proto
);
70 void IoODESimpleSpace_free(IoODESimpleSpace
*self
)
74 dSpaceDestroy(SPACEID
);
78 free(IoObject_dataPointer(self
));
81 void IoODESimpleSpace_mark(IoODESimpleSpace
*self
)
85 /* ----------------------------------------------------------- */
87 dSpaceID
IoODESimpleSpace_rawSimpleSpaceId(IoODESimpleSpace
*self
)
92 /* ----------------------------------------------------------- */
94 void IoODESimpleSpace_assertHasSimpleSpaceId(IoODESimpleSpace
*self
, IoObject
*locals
, IoMessage
*m
)
96 IOASSERT(SPACEID
, "ODE SimpleSpace cannot be used directly. Clone the space and use the clone.");
100 IoObject
*IoODESimpleSpace_spaceId(IoODESimpleSpace
*self
, IoObject
*locals
, IoMessage
*m
)
102 return IONUMBER((long)SPACEID
);
105 IoObject
*IoODESimpleSpace_plane(IoODESimpleSpace
*self
, IoObject
*locals
, IoMessage
*m
)
107 dReal a
= IoMessage_locals_doubleArgAt_(m
, locals
, 0);
108 dReal b
= IoMessage_locals_doubleArgAt_(m
, locals
, 1);
109 dReal c
= IoMessage_locals_doubleArgAt_(m
, locals
, 2);
110 dReal d
= IoMessage_locals_doubleArgAt_(m
, locals
, 3);
113 // Don't require a valid space. Plane can be used on the proto to create a plane without a space.
114 //IoODESimpleSpace_assertHasSimpleSpaceId(self, locals, m);
116 geomId
= dCreatePlane(SPACEID
, a
, b
, c
, d
);
118 return IoODEPlane_new(IOSTATE
, geomId
);
121 IoObject
*IoODESimpleSpace_box(IoODESimpleSpace
*self
, IoObject
*locals
, IoMessage
*m
)
123 dReal lx
= IoMessage_locals_doubleArgAt_(m
, locals
, 0);
124 dReal ly
= IoMessage_locals_doubleArgAt_(m
, locals
, 1);
125 dReal lz
= IoMessage_locals_doubleArgAt_(m
, locals
, 2);
129 // Don't require a valid space. Box can be used on the proto to create a box without a space.
130 //IoODESimpleSpace_assertHasSimpleSpaceId(self, locals, m);
132 geomId
= dCreateBox(SPACEID
, lx
, ly
, lz
);
134 return IoODEBox_new(IOSTATE
, geomId
);
137 void nearCallback(void *data
, dGeomID o1
, dGeomID o2
);
146 IoObject
*IoODESimpleSpace_collide(IoODESimpleSpace
*self
, IoObject
*locals
, IoMessage
*m
)
148 NearCallbackData data
;
150 data
.target
= IoMessage_locals_valueArgAt_(m
, locals
, 0);
151 data
.message
= IoMessage_locals_messageArgAt_(m
, locals
, 1);
152 data
.locals
= locals
;
154 IoODESimpleSpace_assertHasSimpleSpaceId(self
, locals
, m
);
156 dSpaceCollide (SPACEID
, &data
, &nearCallback
);
160 void nearCallback(void *data
, dGeomID o1
, dGeomID o2
)
162 // This callback creates and disposes of a new mesage each time.
163 // TODO: Reuse message objects to go faster and releave pressure on the GC.
164 NearCallbackData
*nearData
= (NearCallbackData
*)data
;
166 IoMessage
*self
= IoMessage_deepCopyOf_(nearData
->message
);
168 IoMessage_addCachedArg_(self
, IoODEGeom_geomFromId(IOSTATE
, o1
));
169 IoMessage_addCachedArg_(self
, IoODEGeom_geomFromId(IOSTATE
, o2
));
171 IoMessage_locals_performOn_(self
, nearData
->locals
, nearData
->target
);