1 /*************************************************************************
2  *                          D bindings for ODE                           *
3  *                                                                       *
4  *       C header port by Daniel "q66" Kolesa <quaker66@gmail.com>       *
5  *                                                                       *
6  * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
7  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
8  *                                                                       *
9  * This library is free software; you can redistribute it and/or         *
10  * modify it under the terms of EITHER:                                  *
11  *   (1) The GNU Lesser General Public License as published by the Free  *
12  *       Software Foundation; either version 2.1 of the License, or (at  *
13  *       your option) any later version. The text of the GNU Lesser      *
14  *       General Public License is included with this library in the     *
15  *       file LICENSE.TXT.                                               *
16  *   (2) The BSD-style license that is included with this library in     *
17  *       the file LICENSE-BSD.TXT.                                       *
18  *                                                                       *
19  * This library is distributed in the hope that it will be useful,       *
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
22  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
23  *                                                                       *
24  *************************************************************************/
25 
26 /*
27  * TriMesh code by Erwin de Vries.
28  *
29  * Trimesh data.
30  * This is where the actual vertexdata (pointers), and BV tree is stored.
31  * Vertices should be single precision!
32  * This should be more sophisticated, so that the user can easyly implement
33  * another collision library, but this is a lot of work, and also costs some
34  * performance because some data has to be copied.
35  */
36 
37 module deimos.ode.collision_trimesh;
38 
39 private import deimos.ode.common;
40 
41 extern (C):
42 nothrow:
43 
44 /*
45  * Data storage for triangle meshes.
46  */
47 struct dxTriMeshData;
48 alias dxTriMeshData* dTriMeshDataID;
49 
50 /*
51  * These dont make much sense now, but they will later when we add more
52  * features.
53  */
54 dTriMeshDataID dGeomTriMeshDataCreate();
55 void dGeomTriMeshDataDestroy(dTriMeshDataID g);
56 
57 
58 
59 enum { TRIMESH_FACE_NORMALS }
60 void  dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data);
61 void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id);
62 
63 /**
64  * We need to set the last transform after each time step for 
65  * accurate collision response. These functions get and set that transform.
66  * It is stored per geom instance, rather than per dTriMeshDataID.
67  */
68 void dGeomTriMeshSetLastTransform(dGeomID g, dMatrix4 last_trans);
69 dReal* dGeomTriMeshGetLastTransform(dGeomID g);
70 
71 /*
72  * Build a TriMesh data object with single precision vertex data.
73  */
74 void dGeomTriMeshDataBuildSingle(
75     dTriMeshDataID g, in void* Vertices, int VertexStride, int VertexCount,
76     in void* Indices, int IndexCount, int TriStride
77 );
78 /* same again with a normals array (used as trimesh-trimesh optimization) */
79 void dGeomTriMeshDataBuildSingle1(
80     dTriMeshDataID g, in void* Vertices, int VertexStride, int VertexCount, 
81     in void* Indices, int IndexCount, int TriStride, in void* Normals
82 );
83 /*
84 * Build a TriMesh data object with double precision vertex data.
85 */
86 void dGeomTriMeshDataBuildDouble(
87     dTriMeshDataID g, in void* Vertices, int VertexStride, int VertexCount,
88     in void* Indices, int IndexCount, int TriStride
89 );
90 /* same again with a normals array (used as trimesh-trimesh optimization) */
91 void dGeomTriMeshDataBuildDouble1(
92     dTriMeshDataID g, in void* Vertices,  int VertexStride,
93     int VertexCount,  in void* Indices, int IndexCount,
94     int TriStride, in void* Normals
95 );
96 
97 /*
98  * Simple build. Single/double precision based on dSINGLE/dDOUBLE!
99  */
100 void dGeomTriMeshDataBuildSimple(
101     dTriMeshDataID g, in dReal* Vertices, int VertexCount,
102     in dTriIndex* Indices, int IndexCount
103 );
104 /* same again with a normals array (used as trimesh-trimesh optimization) */
105 void dGeomTriMeshDataBuildSimple1(
106     dTriMeshDataID g, in dReal* Vertices, int VertexCount,
107     in dTriIndex* Indices, int IndexCount, in int* Normals
108 );
109 
110 /* Preprocess the trimesh data to remove mark unnecessary edges and vertices */
111 void dGeomTriMeshDataPreprocess(dTriMeshDataID g);
112 /* Get and set the internal preprocessed trimesh data buffer, for loading and saving */
113 void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, ubyte** buf, int* bufLen);
114 void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, ubyte*  buf);
115 
116 
117 /*
118  * Per triangle callback. Allows the user to say if he wants a collision with
119  * a particular triangle.
120  */
121 alias int function(
122     dGeomID TriMesh, dGeomID RefObject, int TriangleIndex
123 ) dTriCallback;
124 void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback);
125 dTriCallback* dGeomTriMeshGetCallback(dGeomID g);
126 
127 /*
128  * Per object callback. Allows the user to get the list of triangles in 1
129  * shot. Maybe we should remove this one.
130  */
131 alias void function(
132     dGeomID TriMesh, dGeomID RefObject, in int* TriIndicies, int TriCount
133 ) dTriArrayCallback;
134 void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback);
135 dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g);
136 
137 /*
138  * Ray callback.
139  * Allows the user to say if a ray collides with a triangle on barycentric
140  * coords. The user can for example sample a texture with alpha transparency
141  * to determine if a collision should occur.
142  */
143 alias int function(
144     dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v
145 ) dTriRayCallback;
146 void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback);
147 dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g);
148 
149 /*
150  * Triangle merging callback.
151  * Allows the user to generate a fake triangle index for a new contact generated
152  * from merging of two other contacts. That index could later be used by the 
153  * user to determine attributes of original triangles used as sources for a 
154  * merged contact.
155  */
156 alias int function(
157     dGeomID TriMesh, int FirstTriangleIndex, int SecondTriangleIndex
158 ) dTriTriMergeCallback;
159 void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback);
160 dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g);
161 
162 /*
163  * Trimesh class
164  * Construction. Callbacks are optional.
165  */
166 dGeomID dCreateTriMesh(
167     dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback,
168     dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback
169 );
170 
171 void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data);
172 dTriMeshDataID dGeomTriMeshGetData(dGeomID g);
173 
174 
175 // enable/disable/check temporal coherence
176 void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable);
177 int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass);
178 
179 /*
180  * Clears the internal temporal coherence caches. When a geom has its
181  * collision checked with a trimesh once, data is stored inside the trimesh.
182  * With large worlds with lots of seperate objects this list could get huge.
183  * We should be able to do this automagically.
184  */
185 void dGeomTriMeshClearTCCache(dGeomID g);
186 
187 
188 /*
189  * returns the TriMeshDataID
190  */
191 dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g);
192 
193 /*
194  * Gets a triangle.
195  */
196 void dGeomTriMeshGetTriangle(
197     dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2
198 );
199 
200 /*
201  * Gets the point on the requested triangle and the given barycentric
202  * coordinates.
203  */
204 void dGeomTriMeshGetPoint(
205     dGeomID g, int Index, dReal u, dReal v, dVector3 Out
206 );
207 
208 /*
209 
210 This is how the strided data works:
211 
212 struct StridedVertex{
213     dVector3 Vertex;
214     // Userdata
215 };
216 int VertexStride = sizeof(StridedVertex);
217 
218 struct StridedTri{
219     int Indices[3];
220     // Userdata
221 };
222 int TriStride = sizeof(StridedTri);
223 
224 */
225 
226 
227 int dGeomTriMeshGetTriangleCount(dGeomID g);
228 
229 void dGeomTriMeshDataUpdate(dTriMeshDataID g);