Skip to content

Commit 96118da

Browse files
quaglacopybara-github
authored andcommitted
Move SDF precomputation to the mujoco compiler.
Before: ``` Simulation time : 2.24 s Steps per second : 4472 Realtime factor : 8.94 x Time per step : 223.6 µs Newton iters / step : 2.47 Contacts / step : 3.37 Constraints / step : 13.49 Degrees of freedom : 12 Dynamic memory usage : 0.2% of 14M ``` After: ``` Simulation time : 1.71 s Steps per second : 5854 Realtime factor : 11.71 x Time per step : 170.8 µs Newton iters / step : 2.19 Contacts / step : 3.45 Constraints / step : 13.79 Degrees of freedom : 12 Dynamic memory usage : 0.2% of 14M ``` PiperOrigin-RevId: 781075182 Change-Id: Ie509047ff581ab0df4b10bbd394c27d350ab5a13
1 parent a3d251f commit 96118da

File tree

10 files changed

+45
-32
lines changed

10 files changed

+45
-32
lines changed

doc/includes/references.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,6 +1098,7 @@ struct mjModel_ {
10981098
int* oct_depth; // depth in the octree (noct x 1)
10991099
int* oct_child; // children of octree node (noct x 8)
11001100
mjtNum* oct_aabb; // octree node bounding box (center, size) (noct x 6)
1101+
mjtNum* oct_coeff; // octree interpolation coefficients (noct x 8)
11011102

11021103
// joints
11031104
int* jnt_type; // type of joint (mjtJoint) (njnt x 1)

include/mujoco/mjmodel.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,7 @@ struct mjModel_ {
771771
int* oct_depth; // depth in the octree (noct x 1)
772772
int* oct_child; // children of octree node (noct x 8)
773773
mjtNum* oct_aabb; // octree node bounding box (center, size) (noct x 6)
774+
mjtNum* oct_coeff; // octree interpolation coefficients (noct x 8)
774775

775776
// joints
776777
int* jnt_type; // type of joint (mjtJoint) (njnt x 1)

include/mujoco/mjxmacro.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@
220220
X ( int, oct_depth, noct, 1 ) \
221221
X ( int, oct_child, noct, 8 ) \
222222
X ( mjtNum, oct_aabb, noct, 6 ) \
223+
X ( mjtNum, oct_coeff, noct, 8 ) \
223224
X ( int, jnt_type, njnt, 1 ) \
224225
X ( int, jnt_qposadr, njnt, 1 ) \
225226
X ( int, jnt_dofadr, njnt, 1 ) \

plugin/sdf/sdflib.cc

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <utility>
1919
#include <vector>
2020

21-
#include <TriangleMeshDistance/include/tmd/TriangleMeshDistance.h>
2221
#include <mujoco/mjplugin.h>
2322
#include <mujoco/mujoco.h>
2423
#include "sdf.h"
@@ -140,44 +139,19 @@ std::optional<SdfLib> SdfLib::Create(const mjModel* m, mjData* d,
140139
break;
141140
}
142141
}
143-
int meshid = m->geom_dataid[geomid];
144-
int nvert = m->mesh_vertnum[meshid];
145-
int nface = m->mesh_facenum[meshid];
146-
int* indices = m->mesh_face + 3*m->mesh_faceadr[meshid];
147-
float* verts = m->mesh_vert + 3*m->mesh_vertadr[meshid];
148-
std::vector<double> vertices(3*nvert);
149-
for (int i = 0; i < nvert; i++) {
150-
mjtNum vert[3] = {verts[3*i+0], verts[3*i+1], verts[3*i+2]};
151-
mju_rotVecQuat(vert, vert, m->mesh_quat + 4*meshid);
152-
mju_addTo3(vert, m->mesh_pos + 3*meshid);
153-
vertices[3*i+0] = vert[0];
154-
vertices[3*i+1] = vert[1];
155-
vertices[3*i+2] = vert[2];
156-
}
157-
tmd::TriangleMeshDistance mesh(vertices.data(), nvert, indices, nface);
158-
return SdfLib(mesh, m, meshid);
142+
return SdfLib(m, m->geom_dataid[geomid]);
159143
}
160144

161145
// plugin constructor
162-
SdfLib::SdfLib(const tmd::TriangleMeshDistance& sdf, const mjModel* m,
163-
int meshid) {
164-
// TODO: do not evaluate the SDF multiple times at the same vertex
165-
// TODO: the value at hanging vertices should be computed from the parent
146+
SdfLib::SdfLib(const mjModel* m, int meshid) {
166147
int octadr = m->mesh_octadr[meshid];
167148
int octnum = m->mesh_octnum[meshid];
168149
oct_aabb_.assign(m->oct_aabb + 6*octadr,
169150
m->oct_aabb + 6*octadr + 6*octnum);
170151
oct_child_.assign(m->oct_child + 8 * octadr,
171152
m->oct_child + 8 * octadr + 8 * octnum);
172-
for (int i = 0; i < octnum; ++i) {
173-
for (int j = 0; j < 8; j++) {
174-
mjtNum v[3];
175-
v[0] = oct_aabb_[6*i+0] + (j&1 ? 1 : -1) * oct_aabb_[6*i+3];
176-
v[1] = oct_aabb_[6*i+1] + (j&2 ? 1 : -1) * oct_aabb_[6*i+4];
177-
v[2] = oct_aabb_[6*i+2] + (j&4 ? 1 : -1) * oct_aabb_[6*i+5];
178-
sdf_coeff_.push_back(sdf.signed_distance(v).distance);
179-
}
180-
}
153+
sdf_coeff_.assign(8 * octnum, 0);
154+
memcpy(sdf_coeff_.data(), m->oct_coeff + 8*octadr, 8*octnum*sizeof(mjtNum));
181155
mju_copy(box_, m->oct_aabb + 6*octadr, 6);
182156
}
183157

plugin/sdf/sdflib.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include <mujoco/mjtnum.h>
2424
#include <mujoco/mjvisualize.h>
2525
#include "sdf.h"
26-
#include <TriangleMeshDistance/include/tmd/TriangleMeshDistance.h>
2726

2827
namespace mujoco::plugin::sdf {
2928
class SdfLib {
@@ -44,7 +43,7 @@ class SdfLib {
4443
static void RegisterPlugin();
4544

4645
private:
47-
SdfLib(const tmd::TriangleMeshDistance& sdf, const mjModel* m, int meshid);
46+
SdfLib(const mjModel* m, int meshid);
4847
SdfVisualizer visualizer_;
4948
std::vector<double> sdf_coeff_;
5049

python/mujoco/introspect/structs.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,14 @@
15891589
doc='octree node bounding box (center, size)',
15901590
array_extent=('noct', 6),
15911591
),
1592+
StructFieldDecl(
1593+
name='oct_coeff',
1594+
type=PointerType(
1595+
inner_type=ValueType(name='mjtNum'),
1596+
),
1597+
doc='octree interpolation coefficients',
1598+
array_extent=('noct', 8),
1599+
),
15921600
StructFieldDecl(
15931601
name='jnt_type',
15941602
type=PointerType(

src/user/user_mesh.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include <mujoco/mjspec.h>
3434
#include "user/user_api.h"
35+
#include <TriangleMeshDistance/include/tmd/TriangleMeshDistance.h>
3536

3637
#ifdef MUJOCO_TINYOBJLOADER_IMPL
3738
#define TINYOBJLOADER_IMPLEMENTATION
@@ -1548,6 +1549,25 @@ void mjCMesh::Process() {
15481549
}
15491550
octree_.SetFace(vert_, face_);
15501551
octree_.CreateOctree(aamm);
1552+
1553+
// compute sdf coefficients
1554+
// TODO: only check !plugin.active once sdflib is removed
1555+
if (plugin.active && *plugin.name == "sdf") {
1556+
tmd::TriangleMeshDistance sdf(vert_.data(), nvert(), face_.data(), nface());
1557+
1558+
// TODO: do not evaluate the SDF multiple times at the same vertex
1559+
// TODO: the value at hanging vertices should be computed from the parent
1560+
const double* nodes = octree_.Nodes().data();
1561+
for (int i = 0; i < octree_.NumNodes(); ++i) {
1562+
for (int j = 0; j < 8; j++) {
1563+
mjtNum v[3];
1564+
v[0] = nodes[6*i+0] + (j&1 ? 1 : -1) * nodes[6*i+3];
1565+
v[1] = nodes[6*i+1] + (j&2 ? 1 : -1) * nodes[6*i+4];
1566+
v[2] = nodes[6*i+2] + (j&4 ? 1 : -1) * nodes[6*i+5];
1567+
octree_.AddCoeff(sdf.signed_distance(v).distance);
1568+
}
1569+
}
1570+
}
15511571
}
15521572

15531573
// transform CoM to origin

src/user/user_model.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2997,6 +2997,11 @@ void mjCModel::CopyObjects(mjModel* m) {
29972997
memcpy(m->oct_aabb + 6*oct_adr, pme->octree().Nodes().data(), 6*n_oct*sizeof(mjtNum));
29982998
memcpy(m->oct_child + 8*oct_adr, pme->octree().Child().data(), 8*n_oct*sizeof(int));
29992999
memcpy(m->oct_depth + oct_adr, pme->octree().Level().data(), n_oct*sizeof(int));
3000+
if (!pme->octree().Coeff().empty()) {
3001+
memcpy(m->oct_coeff + 8*oct_adr, pme->octree().Coeff().data(), 8*n_oct*sizeof(mjtNum));
3002+
} else {
3003+
mjuu_zerovec(m->oct_coeff + 8*oct_adr, 8*n_oct);
3004+
}
30003005
}
30013006

30023007
// advance counters

src/user/user_objects.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ struct mjCOctree_ {
222222
std::vector<int> child_; // children of each node (nnode x 8)
223223
std::vector<double> node_; // bounding boxes (nnode x 6)
224224
std::vector<int> level_; // levels of each node (nnode x 1)
225+
std::vector<double> coeff_; // interpo coefficients (nnode x 8)
225226
std::vector<Triangle> face_; // mesh faces (nface x 3)
226227
double ipos_[3] = {0, 0, 0};
227228
double iquat_[4] = {1, 0, 0, 0};
@@ -246,6 +247,8 @@ class mjCOctree : public mjCOctree_ {
246247
level_.clear();
247248
face_.clear();
248249
}
250+
void AddCoeff(double coeff) { coeff_.push_back(coeff); }
251+
const std::vector<double>& Coeff() const { return coeff_; }
249252

250253
private:
251254
void Make(std::vector<Triangle>& elements);

unity/Runtime/Bindings/MjBindings.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5364,6 +5364,7 @@ public unsafe struct mjModel_ {
53645364
public int* oct_depth;
53655365
public int* oct_child;
53665366
public double* oct_aabb;
5367+
public double* oct_coeff;
53675368
public int* jnt_type;
53685369
public int* jnt_qposadr;
53695370
public int* jnt_dofadr;

0 commit comments

Comments
 (0)